使用反射的非虚方法调用

时间:2017-08-24 03:27:56

标签: java reflection

在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就足够了。显然我错了,如何才能使用反射获得所需的行为?

1 个答案:

答案 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);
  }
}

确实打印出“好”