在Java中,使用java.lang.reflect.Method
时如何在不进行虚拟调用的情况下调用函数?
即。我希望这段代码能够打印出“好”而不是它目前所做的,这就是打印“坏”:
Foo.java:
public class Foo {
public void doit() {
System.out.println("good");
}
}
Bar.java:
import java.lang.reflect.Method;
public class Bar extends Foo {
public void doit() {
System.out.println("bad");
}
public static void main(String[] args) throws Exception {
Bar b = new Bar();
/* Using Foo.class ought to do it right? */
Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
/* Surely if that didn't do it casting to Foo would? */
m.invoke((Foo)b, new Object[]{});
}
}
我使用反射做的任何事都没有成功打印出“好”。
我的期望是使用一个或多个将invoke
的第一个参数投射到Foo
,和/或使用Foo.class.getDeclaredMethod
代替Bar.class
就足够了。显然我错了,如何才能使用反射获得所需的行为?
答案 0 :(得分:3)
似乎最简单的解决方案是使用java.lang.invoke
包,它有一个名为unreflectSpecial
的方法来模拟和调用特殊指令:
import java.lang.reflect.Method;
import java.lang.invoke.*;
public class Bar extends Foo {
public void doit() {
System.out.println("bad");
}
public static void main(String[] args) throws Throwable {
Bar b = new Bar();
Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
MethodHandle h = MethodHandles.lookup().unreflectSpecial(m, Bar.class);
h.invoke(b);
}
}
确实打印出“好”