Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I lookup an array constructor MethodHandle with MethodHandles.Lookup?

How do I get the MethodHandle for an array constructor like int[]::new?

This doesn't work:

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());
}

It results in this:

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

Nor does this:

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());
}

It seems to find the constructor for Object instead:

MethodHandle()Object
java.lang.Object@36baf30c
like image 463
Archie Avatar asked Mar 18 '16 02:03

Archie


Video Answer


1 Answers

As I know int[].class has no constructor, so it's not available via reflection at least.

Instead, you can try to get MethodHandle on Array's factory method:

MethodHandle mh = lookup.findStatic(Array.class, "newInstance",
                             MethodType.methodType(Object.class, Class.class, int.class));

and create an array by calling it.

like image 140
ivanenok Avatar answered Sep 18 '22 10:09

ivanenok