Java 8 个数组构造函数引用如何工作?
How do Java 8 array constructor references work?
假设我们有一个 IntFunction
类型的变量,returns 一个整数数组:
IntFunction<int[]> i;
使用 Java 8 个泛型,可以使用构造函数引用初始化此变量,如下所示:
i = int[]::new
Java 编译器如何将其转换为字节码?
我知道对于其他类型,比如String::new
,它可以使用一个invokedynamic
指令指向String构造函数java/lang/String.<init>(...)
,这只是一个具有特殊含义的方法.
这对数组有何作用,看到有构造数组的特殊说明?
你可以通过反编译java字节码找到自己:
javap -c -v -p MyClass.class
编译器将数组构造函数引用 Foo[]::new
脱糖到 lambda (i -> new Foo[i]
),然后像处理任何其他 lambda 或方法引用一样继续处理。这是这个合成 lambda 的反汇编字节码:
private static java.lang.Object lambda$MR$new$new5084e0(int);
descriptor: (I)Ljava/lang/Object;
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: anewarray #6 // class java/lang/String
4: areturn
(return类型是Object,因为IntFunction中擦除的return类型是Object。)
假设我们有一个 IntFunction
类型的变量,returns 一个整数数组:
IntFunction<int[]> i;
使用 Java 8 个泛型,可以使用构造函数引用初始化此变量,如下所示:
i = int[]::new
Java 编译器如何将其转换为字节码?
我知道对于其他类型,比如String::new
,它可以使用一个invokedynamic
指令指向String构造函数java/lang/String.<init>(...)
,这只是一个具有特殊含义的方法.
这对数组有何作用,看到有构造数组的特殊说明?
你可以通过反编译java字节码找到自己:
javap -c -v -p MyClass.class
编译器将数组构造函数引用 Foo[]::new
脱糖到 lambda (i -> new Foo[i]
),然后像处理任何其他 lambda 或方法引用一样继续处理。这是这个合成 lambda 的反汇编字节码:
private static java.lang.Object lambda$MR$new$new5084e0(int);
descriptor: (I)Ljava/lang/Object;
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: anewarray #6 // class java/lang/String
4: areturn
(return类型是Object,因为IntFunction中擦除的return类型是Object。)