hen*_*nry 8 java lambda stack-trace java-8 method-reference
我刚刚在Eclipse中进行了快速实验.
public class StackTractTest {
static class Nasty {
public Integer toInt() {
if (1 == 1) throw new RuntimeException();
return 1;
}
}
@Test
public void methodReference() {
Stream.of(new Nasty())
.map(Nasty::toInt)
.findFirst();
}
@Test
public void lambda() {
Stream.of(new Nasty())
.map(n -> n.toInt())
.findFirst();
}
}
Run Code Online (Sandbox Code Playgroud)
当方法引用测试失败时,跟踪开始
java.lang.RuntimeException
at com.example.StackTractTest$Nasty.toInt(StackTractTest.java:11)
at com.example.StackTractTest$$Lambda$1/1681433494.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
Run Code Online (Sandbox Code Playgroud)
虽然跟踪的末尾(未显示)确实链接回到具有findFirst
on的行,但是没有对使用方法引用的行的引用.
而lamdba stacktrace开始了
java.lang.RuntimeException
at com.example.StackTractTest$Nasty.toInt(StackTractTest.java:11)
at com.example.StackTractTest.lambda$0(StackTractTest.java:26)
at com.example.StackTractTest$$Lambda$1/1681433494.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
Run Code Online (Sandbox Code Playgroud)
第26行使用了正确识别lambda的方法.
这是Eclipse编译器的特性还是使用方法引用的一般缺点,在选择它们和lambda时应该考虑这些引用?
不,这是当前的实现方式。
引用的论文 Brian Goetz撰写有关lambda表达式的翻译写:
当编译器遇到lambda表达式时,它首先将lambda主体降低(删除)到其参数列表和返回类型与lambda表达式的参数匹配的方法中
...
方法引用与lambda表达式的处理方式相同,不同之处在于,大多数方法引用不需要分解为新方法;我们可以简单地为引用的方法加载一个常量方法句柄,并将其传递给元工厂。
您的两个堆栈跟踪之间的唯一区别是,带有显式lambda的堆栈跟踪添加了以下行:
at com.example.StackTractTest.lambda$0(StackTractTest.java:26)
Run Code Online (Sandbox Code Playgroud)
这是因为将lambda转换javac
为新生成的方法,并且您实际上可以在stacktrace中看到该新方法是lambda$0
。
使用方法引用时,无需生成新方法,因为它直接引用现有方法。
归档时间: |
|
查看次数: |
183 次 |
最近记录: |