Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用MethodHandles.lookup查找数组构造函数MethodHandle?_Java_Java 8_Methodhandle - Fatal编程技术网

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

Java 如何使用MethodHandles.lookup查找数组构造函数MethodHandle?,java,java-8,methodhandle,Java,Java 8,Methodhandle,如何获取数组构造函数(如int[]::new)的MethodHandle 这不起作用: public static void main(String[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.publicLookup(); MethodHandle mh = lookup.findConstructor(int[].class, MethodType.methodType(void

如何获取数组构造函数(如
int[]::new
)的
MethodHandle

这不起作用:

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());
}
其结果是:

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
它似乎找到了
对象的构造函数

MethodHandle()Object
java.lang.Object@36baf30c

正如我所知,
int[].class
没有构造函数,所以它至少不能通过反射使用

相反,您可以尝试在数组的工厂方法上获取
MethodHandle

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

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

似乎@MaximSIvanov是对的:没有内置的方法来获得这样的方法句柄。但是,没有任何东西可以阻止您为此目的创建特殊方法,并提供此方法的句柄:

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;

public class ArrayMethodHandles {
    private static int[] makeIntArray(int size) {
        return new int[size];
    }

    public static MethodHandle createIntArray() {
        try {
            return MethodHandles.lookup().findStatic(ArrayMethodHandles.class, 
                "makeIntArray", MethodType.methodType(int[].class, int.class));
        } catch (NoSuchMethodException | IllegalAccessException e) {
            throw new InternalError();
        }
    }

    public static void main(String[] args) throws Throwable {
        MethodHandle mh = createIntArray();
        int[] array = (int[])mh.invokeExact(10);
        System.out.println(Arrays.toString(array));
        // prints [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    }
}
当编译
int[]时,java编译器实际上会执行类似的操作:新建
方法引用:创建助手私有方法。您可以通过编译以下类进行检查:

import java.util.function.*;

public class Test { 
    IntFunction<int[]> fn = int[]::new;
}

刚刚检查了
int[]::new
在字节码合成方法中生成,比如
对象lambda$MR$new$new$4ffde7b3$1(int len){返回新的int[len];}
。在这个问题的上下文中,您肯定希望链接一个
.bindTo(int.class).asType(MethodType.MethodType(int[].class,int.class))
获取表示
int[]的所需句柄:新建
逻辑,即可以像
int[]数组=(int[])mh.invokeExact(42)那样使用它然后谢谢大家。这对我很有用:
MethodHandles.insertArguments(lookup.findStatic(Array.class,“newInstance”,MethodType.MethodType(Object.class,class.class,int.class)),0,int.class)
在Java 9中添加了一个静态工厂方法:
MethodHandles.arrayConstructor(int[].class)
import java.util.function.*;

public class Test { 
    IntFunction<int[]> fn = int[]::new;
}
private static java.lang.Object lambda$MR$new$new$4ffde7b3$1(int);
    Code:
       0: iload_0
       1: newarray       int
       3: areturn