使用 Java 8 个流时的新对象实例化
New object instantiation when using Java 8 streams
除了后者的可读性稍好之外,使用以下结构是否有区别?
someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());
someList.stream().map(NewClass::new).collect(Collectors.toList());
一般来说没有区别。 NewClass::new
产生较少的字节码,因为在 lambda 版本中,java 编译器从 lambda 主体创建自动生成的私有方法,而 NewClass:new
直接链接到构造方法句柄。因此,使用方法参考,您的文件大小可能会略小 class。不过预计不会有明显的性能差异。
另一个区别是方法解析过程。它不适用于您的特定示例,但可能适用于其他代码。例如,您有两个构造函数:
public NewClass(String a) {...}
public NewClass(String a, String b) {...}
并且你有一些接受功能接口的方法:
public myMethod(Function<String, NewClass> fn) {...}
然后你可以用 lambda 或函数接口调用它:
myMethod(str -> new NewClass(str));
myMethod(NewClass::new);
但是假设稍后您添加了一个具有相同名称的新方法,如下所示:
public myMethod(BiFunction<String, String, NewClass> fn) {...}
然后方法引用调用将变得不明确并导致编译错误,因为 NewClass::new
现在匹配两个构造函数,而 lambda 仍然是明确的。
除了后者的可读性稍好之外,使用以下结构是否有区别?
someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());
someList.stream().map(NewClass::new).collect(Collectors.toList());
一般来说没有区别。 NewClass::new
产生较少的字节码,因为在 lambda 版本中,java 编译器从 lambda 主体创建自动生成的私有方法,而 NewClass:new
直接链接到构造方法句柄。因此,使用方法参考,您的文件大小可能会略小 class。不过预计不会有明显的性能差异。
另一个区别是方法解析过程。它不适用于您的特定示例,但可能适用于其他代码。例如,您有两个构造函数:
public NewClass(String a) {...}
public NewClass(String a, String b) {...}
并且你有一些接受功能接口的方法:
public myMethod(Function<String, NewClass> fn) {...}
然后你可以用 lambda 或函数接口调用它:
myMethod(str -> new NewClass(str));
myMethod(NewClass::new);
但是假设稍后您添加了一个具有相同名称的新方法,如下所示:
public myMethod(BiFunction<String, String, NewClass> fn) {...}
然后方法引用调用将变得不明确并导致编译错误,因为 NewClass::new
现在匹配两个构造函数,而 lambda 仍然是明确的。