如何在JDK 6中使用方法句柄?

时间:2015-04-27 22:56:57

标签: java reflection jdk1.6 methodhandle

这里奇怪的情况。我需要多次调用相同的类实例方法(1000 /秒范围),而无需导入或构建所需的库。我试图在我的JEE项目中调用一个方法,该方法使用来自应用程序服务器提供的库的类。 JEE项目仍然需要在其他应用程序服务器上运行,因此我不能简单地针对该库进行构建。反思是我认为的唯一解决方案。

当进行得如此之快时,使用反射执行的时间比直接调用慢几个数量级。

经过一番研究,我发现了静态最终的MethodHandles:

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;



public class Test {

    static final MethodHandle sfmh;

    static {
        MethodHandle mh = null;
        try {
            final Class<?> clazz = Class.forName("com.me.lib");
            Method m = clazz.getMethod("MyMethod");
            mh = MethodHandles.lookup().unreflect(m);
        } catch (Throwable e) {
            mh = null;
        }

        sfmh = mh;
    }

    public static void main(String[] args) throws Throwable {
        int i = 0;
        System.out.println("starting");
        long start = System.currentTimeMillis();
        for(i = 0; i < 1000000000; i++) {
            sfmh.invokeExact();
        }
        long total = System.currentTimeMillis() - start;
        System.out.println("Time: " + total + " milliseconds");
    }

}

效果很好,让我得到一个可接受的速度结果(慢2-4倍而不是200倍慢)。这个完美的解决方案似乎存在一个问题 - 我需要在Java 6上运行(嘘声,嘶嘶声,这是一个要求)

当针对1.6进行编译时,我得到:

  

下面的源级别不允许调用多态方法   1.7

就行了

sfmh.invokeExact();

是否有任何解决方案可以利用与1.6一起使用的MethodHandle概念?

1 个答案:

答案 0 :(得分:1)

不,方法句柄仅在JDK 7中添加,在此之前无法访问。您也不能针对方法句柄API编译类,因为JDK 6不理解@PolymorphicSignature注释;方法句柄的编译方式与使用合成签名的其他方法略有不同。

除此之外,现代JVM上的反射速度并不慢,可能会在最近的JVM上运行您的应用程序?在JVM v8上运行Java 6代码是完全正常的。最后,由于许多原因,您的基准存在缺陷。也许你的反射代码即使在今天也不慢? JVM知道一种被称为通胀的概念,它避免了JNI调用的性能开销。

以下是使用v8 JVM上的线束的一些结果,比较了反射,常见调用和方法句柄:https://gist.github.com/raphw/881e1745996f9d314ab0