使用 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 对象时的警告
java Class.forName 实例化对象,并调用类中相应的方法