考虑我们有以下内容:
class Base { def name = "Base" }
class Successor extends Base {
override def name = "Successor"
}
我尝试过以下操作(从How to call a superclass method using Java reflection获取):
import java.lang.invoke.{MethodHandles, MethodHandle, MethodType}
object TestApp {
def main(args: Array[String]) {
val a = new Successor;
val h1 = MethodHandles.lookup().findSpecial(classOf[Base],
"name",
MethodType.methodType(classOf[String]),
classOf[Successor]);
println(h1.invoke(a));
}
}
但是我得到了运行时异常:
java.lang.IllegalAccessException: no private access for invokespecial: class Successor, from TestApp$
有人告诉我,Java反射可能无法正常用于Scala。这是真的吗?或者我只是做错了什么?
答案 0 :(得分:1)
实际上,你甚至不能用Java做到这一点。注意,在"如何使用Java反射"调用超类方法的答案中,它起作用,因为测试扩展了基础:public class Test extends Base {...}
。
答案 1 :(得分:1)
看起来它是可能的,Java反射也适用于Scala,我只是没有阅读How to call a superclass method using Java reflection的所有答案。
以下代码有效:
object TestApp {
def main(args: Array[String]) {
val a = new Successor;
val impl_lookup = classOf[MethodHandles.Lookup].getDeclaredField("IMPL_LOOKUP")
impl_lookup.setAccessible(true)
val lkp = impl_lookup.get(null).asInstanceOf[MethodHandles.Lookup];
val h1 = lkp.findSpecial(classOf[Base],
"name",
MethodType.methodType(classOf[String]),
classOf[Successor])
println(h1.invoke(a)) // prints "Base"
println(a.name) // prints "Successor"
}
}
感谢此解决方案的Jesse Glick。