可以使用 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 决定重做泛型时,这可能会改变,但我们还没有做到。