gpt4 book ai didi

java - 与 lambda 内的 Class.isInstance 和 Class.cast 方法引用相比,instanceOf 和 () 强制转换

转载 作者:行者123 更新时间:2023-11-30 06:12:27 26 4
gpt4 key购买 nike

在重构一些代码时,我遇到了这段代码

class MyClassB extends MyClassA {...}
// other classes extending from MyClassA

...

List<MyClassA> list = new ArrayList<>();
// fill list
list.stream()
.filter(o -> o instanceof MyClassB)
.map(o -> (MyClassB)o)
.forEach(/* do something */)

实际的代码要大得多,但由于我喜欢尽可能使用方法引用,因此我将流重构为:

list.stream()
.filter(MyClassB.class::isInstance)
.map(MyClassB.class::cast)
.forEach(/* do something */)

我现在想知道这是否更有效?更可取吗?我认为 Java 使用方法引用生成的代码较少,但由于检查 instanceOf 和转换是相当内部的过程,因此是否还会有我没有想到的其他负面影响?
在我看来,它仍然像以前一样具有可读性。任何想法都非常受欢迎。

最佳答案

一旦 JIT 编译器完成其工作,此类构造之间的性能差异通常可以忽略不计。因此,正如其他人所说,更喜欢您认为更具可读性的内容。

如果我们看看性能,在代码优化到最大程度之前,结果有时可能是违反直觉的。

通常,与调用相同方法的 lambda 表达式相比,方法引用在创建站点生成的代码较少,委托(delegate)级别也较低,但在这里,lambda 表达式并没有做同样的事情。

诸如 o -> o instanceof MyClassBo -> (MyClassB)o 之类的 Lambda 表达式是不变的,并且对类 MyClassB 的引用包含在合成目标方法的代码中。相反,方法引用 MyClassB.class::isInstanceMyClassB.class::cast 分别引用方法 Class.isInstanceClass.cast 和方法调用的实际接收者在创建功能接口(interface)实例时捕获。当前的实现无法检测到接收者实例始终相同,因此每次当 Predicate 实例出现时,它都会创建一个新对象。请求函数。相反,对于非捕获 lambda 表达式,它将重用实例。

因此,除非优化器内联整个流管道并成功应用逃逸分析,否则方法引用可能会生成更多对象实例,此外,这些是生成的类的实例,不与要测试或转换到的特定类绑定(bind),但是在实例字段中有实际的Class。与 lambda 表达式相比,这可能存在性能缺陷。但在实践中,你很少会注意到。

关于java - 与 lambda 内的 Class.isInstance 和 Class.cast 方法引用相比,instanceOf 和 () 强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49936809/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com