使用 Java 8 流时的新对象实例化

Posted

技术标签:

【中文标题】使用 Java 8 流时的新对象实例化【英文标题】:New object instantiation when using Java 8 streams 【发布时间】:2015-10-24 04:20:51 【问题描述】:

除了后者的可读性稍好之外,使用以下构造有什么不同吗?

someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());

someList.stream().map(NewClass::new).collect(Collectors.toList());

【问题讨论】:

你的意思是item -> new NewClass(item),对吧? 反对者,您介意解释一下原因吗? 【参考方案1】:

通常没有区别。 NewClass::new 产生更少的字节码,因为在 lambda 版本中,自动生成的私有方法是由 java 编译器从 lambda 主体创建的,而 NewClass:new 直接链接到构造函数方法句柄。因此,使用方法引用您的类文件大小可能会稍微小一些。但预计不会有显着的性能差异。

另一个区别是方法解析过程。它不适用于您的特定示例,但可能适用于其他代码。例如,您有两个构造函数:

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 仍然是明确的。

【讨论】:

同样,当我们有构造函数public NewClass(T data)...,如果我们使用map(NewClass::new),我们会得到一个警告类型安全:构造函数NewClass(Object)属于原始类型NewClass。对泛型类型 NewClass 的引用应该被参数化

以上是关于使用 Java 8 流时的新对象实例化的主要内容,如果未能解决你的问题,请参考以下文章

在 javascript 中实例化 QWebChannel 对象时的警告

实例化领域对象时的 EXC_BAD_INSTRUCTION

使用 Core Data 时的模型实例化问题

java Class.forName 实例化对象,并调用类中相应的方法

使用 vector<vector<int> > 成员实例化对象时的段错误

java中的实例化对象有啥用???????