Ger*_*ard 106 java intellij-idea java-8
IntelliJ一直建议我用方法引用替换我的lambda表达式.
两者之间是否存在客观差异?
Bri*_*etz 163
让我提供一些观点,说明为什么我们将这个特性添加到语言中,显然我们并不是非常需要(所有方法引用都可以表示为lambda).
请注意,没有正确的答案.任何人说"总是使用方法ref而不是lambda"或"总是使用lambda而不是方法ref"应该被忽略.
这个问题在精神上与"何时应该使用命名类与匿名类"非常相似?答案是一样的:当你发现它更具可读性时.当然有一些肯定是一个或绝对是另一个但是中间有一大堆灰色,必须使用判断.
方法refs背后的理论很简单:名称很重要.如果一个方法有一个名称,那么通过名称引用它,而不是通过最终只是转身并调用它的命令包代码,通常(但不总是!)更清晰和可读.
关于表现或关于计算字符的论点大多是红色的鲱鱼,你应该忽略它们.目标是编写清晰明确的代码.很多时候(但并不总是!)方法引用此指标的胜利,因此我们将它们作为选项包含在这些情况下使用.
关于方法引用是否澄清或混淆意图的关键考虑因素是从上下文中是否明显表示所表示的函数的形状.在某些情况下(例如,map(Person::getLastName)从上下文中可以清楚地看到需要将一个函数映射到另一个函数的函数,并且在这种情况下,方法引用会发光.在其他情况下,使用方法ref需要读者想知道什么样的正在描述函数;这是一个警告标志,即lambda可能更具可读性,即使它更长.
最后,我们发现大多数人首先避开方法引用,因为他们觉得比lambdas更新,更怪,因此最初发现它们"不太可读",但随着时间的推移,当他们习惯了语法时,通常会改变他们的行为并尽可能地倾向于方法参考.所以请注意,你自己的主观初始"不太可读"的反应几乎肯定会带来一些熟悉偏见的方面,你应该给自己一个机会在提出风格意见之前对两者都感到满意.
ovu*_*tin 10
由多个语句组成的长lambda表达式可能会降低代码的可读性.在这种情况下,在方法中提取这些语句并引用它可能是更好的选择.
另一个原因可能是可重用性.您可以构造一个方法并从代码的不同位置调用它,而不是复制和粘贴几个语句的lambda表达式.
aer*_*ode 10
正如用户stuchl4n3k在该问题的评论中所写,可能会发生异常。
让我们考虑某个变量field是null,那么:
field = null;
runThisLater(()->field.method());
field = new SomeObject();
Run Code Online (Sandbox Code Playgroud)
不会崩溃,同时
field = null;
runThisLater(field::method);
field = new SomeObject();
Run Code Online (Sandbox Code Playgroud)
会在方法引用语句行处崩溃java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()',至少在 Android 上是这样。
今天的 IntelliJ 在建议进行重构时指出,重构“可能会改变语义”。
当我们“引用”特定对象的实例方法时,就会发生这种情况。为什么?让我们检查 15.13.3 的前两段 。方法参考的运行时评估:
在运行时,方法引用表达式的求值类似于类实例创建表达式的求值,只要正常完成会生成对对象的引用。方法引用表达式的求值与方法本身的调用不同。
首先,如果方法引用表达式以ExpressionName或 Primary开头,则计算此子表达式。如果子表达式的计算结果为 null,
NullPointerException则引发a ,并且方法引用表达式突然完成。如果子表达式突然完成,则方法引用表达式也会出于同样的原因突然完成。
对于 lambda 表达式,我不确定。最终类型是在编译时从方法声明派生的。这只是对正在发生的事情的简化。但是,我们假设该方法runThisLater已声明为
void runThisLater(SamType obj),其中SamType是某个函数接口。然后runThisLater(()->field.method());翻译成这样:
runThisLater(new SamType() {
void doSomething() {
field.method();
}
});
Run Code Online (Sandbox Code Playgroud)
附加信息:
| 归档时间: |
|
| 查看次数: |
23501 次 |
| 最近记录: |