可以使用 Class::method 语法避免对 Lambda 进行装箱和拆箱吗? (Java)
Possible to avoid boxing and unboxing for Lambda using Class::method syntax? (Java)
我最近偶然发现了 Class::method
语法,它允许您插入来自静态方法的 lambda 代码,如下所示:
public class Main {
public static void foo(int foo) {
System.out.println(foo);
}
public static void bar(Consumer<Integer> bar) {
bar.accept(1);
}
public static void main(String[] args) {
bar(Main::foo);
}
}
问题是,1的装箱拆箱还会发生吗?毕竟,bar
的参数是一个Consumer<Integer>
,它通常应该装箱原语,而foo(int)
是一个接受原语的方法,因此不需要装箱。
那么,会发生什么? 1
会变成 Integer
还是保持原始状态?
附带说明一下,我知道 IntConsumer
提供了一种摆脱装箱和拆箱的解决方案,但并非每个功能接口都有针对每个原始类型的替代方案,因此出现了这个问题。
是的,先装箱再拆箱。
编译代码然后反编译 class 文件显示以下内容:
import java.util.function.Consumer;
public class Main {
public Main() {
}
public static void foo(int foo) {
System.out.println(foo);
}
public static void bar(Consumer<Integer> bar) {
bar.accept(Integer.valueOf(1));
}
public static void main(String[] args) {
bar(Main::foo);
}
}
编译器自动装箱 1,这意味着它会在调用 foo() 时取消装箱。
如果您接受的答案让您感到惊讶,那是因为您对 Java 的了解还不够。所以不要称之为失望,而是 幻灭。
与 C++ 模板相比 Java 泛型仅适用于引用类型 。
因此绝对没有任何generic-using构造可以直接使用原始类型的方法!因此,无论何时在这样的上下文中使用原始类型值,它 都必须 装箱。
也许,在遥远的未来某一天,当 Java 的 parents 决定重做泛型时,这可能会改变,但我们还没有做到。
我最近偶然发现了 Class::method
语法,它允许您插入来自静态方法的 lambda 代码,如下所示:
public class Main {
public static void foo(int foo) {
System.out.println(foo);
}
public static void bar(Consumer<Integer> bar) {
bar.accept(1);
}
public static void main(String[] args) {
bar(Main::foo);
}
}
问题是,1的装箱拆箱还会发生吗?毕竟,bar
的参数是一个Consumer<Integer>
,它通常应该装箱原语,而foo(int)
是一个接受原语的方法,因此不需要装箱。
那么,会发生什么? 1
会变成 Integer
还是保持原始状态?
附带说明一下,我知道 IntConsumer
提供了一种摆脱装箱和拆箱的解决方案,但并非每个功能接口都有针对每个原始类型的替代方案,因此出现了这个问题。
是的,先装箱再拆箱。
编译代码然后反编译 class 文件显示以下内容:
import java.util.function.Consumer;
public class Main {
public Main() {
}
public static void foo(int foo) {
System.out.println(foo);
}
public static void bar(Consumer<Integer> bar) {
bar.accept(Integer.valueOf(1));
}
public static void main(String[] args) {
bar(Main::foo);
}
}
编译器自动装箱 1,这意味着它会在调用 foo() 时取消装箱。
如果您接受的答案让您感到惊讶,那是因为您对 Java 的了解还不够。所以不要称之为失望,而是 幻灭。
与 C++ 模板相比 Java 泛型仅适用于引用类型 。
因此绝对没有任何generic-using构造可以直接使用原始类型的方法!因此,无论何时在这样的上下文中使用原始类型值,它 都必须 装箱。
也许,在遥远的未来某一天,当 Java 的 parents 决定重做泛型时,这可能会改变,但我们还没有做到。