如何使用MethodHandles.Lookup查找数组构造函数MethodHandle?

Arc*_*hie 6 java java-8 methodhandle

我如何得到MethodHandle像数组构造函数int[]::new

这不起作用:

public static void main(String[] args) throws Throwable {
    MethodHandles.Lookup lookup = MethodHandles.publicLookup();
    MethodHandle mh = lookup.findConstructor(int[].class, MethodType.methodType(void.class, int.class));
    System.out.println(mh);
    System.out.println(mh.invoke());
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

Exception in thread "main" java.lang.NoSuchMethodException: no such constructor: [I.<init>(int)void/newInvokeSpecial
    at java.lang.invoke.MemberName.makeAccessException(MemberName.java:871)
    at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:990)
    at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1382)
    at java.lang.invoke.MethodHandles$Lookup.findConstructor(MethodHandles.java:920)
    at xx.main(xx.java:11)
Caused by: java.lang.NoSuchMethodError: java.lang.Object.<init>(I)V
    at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
    at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:962)
    at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:987)
    ... 3 more
Run Code Online (Sandbox Code Playgroud)

这也不是:

public static void main(String[] args) throws Throwable {
    MethodHandles.Lookup lookup = MethodHandles.publicLookup();
    MethodHandle mh = lookup.findConstructor(int[].class, MethodType.methodType(void.class));
    System.out.println(mh);
    System.out.println(mh.invoke());
}
Run Code Online (Sandbox Code Playgroud)

它似乎找到了构造函数Object:

MethodHandle()Object
java.lang.Object@36baf30c
Run Code Online (Sandbox Code Playgroud)

iva*_*nok 5

据我所知int[].class,没有构造函数,所以至少不能通过反射来获取它.

相反,您可以尝试MethodHandle使用Array的工厂方法:

MethodHandle mh = lookup.findStatic(Array.class, "newInstance",
                             MethodType.methodType(Object.class, Class.class, int.class));
Run Code Online (Sandbox Code Playgroud)

并通过调用它来创建一个数组.

  • 刚刚检查过`int [] :: new`在字节码合成方法中生成如`Object lambda $ MR $ new $ new $ 4ffde7b3 $ 1(int len){return new int [len]; }`. (2认同)