java - 使用方法引用与 lambda 时,堆栈跟踪的可导航性是否较低?

标签 java lambda java-8 stack-trace 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();
  }

}

当方法引用测试失败时,跟踪开始

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)

虽然跟踪的末尾(未显示)确实链接回使用 findFirst 的行,但没有返回到使用方法引用的行。

当 lamdba 堆栈跟踪开始时

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)

正确识别第 26 行使用的 lambda。

这是 Eclipse 编译器的特性,还是在使用方法引用和 lambda 之间进行选择时应考虑的普遍缺点?

最佳答案

不,这是目前的实现方式。

引用 a paper Brian Goetz 撰写的有关 lambda 表达式翻译的文章:

When the compiler encounters a lambda expression, it first lowers (desugars) the lambda body into a method whose argument list and return type match that of the lambda expression

...

Method references are treated the same way as lambda expressions, except that most method references do not need to be desugared into a new method; we can simply load a constant method handle for the referenced method and pass that to the metafactory.

两个堆栈跟踪之间的唯一区别是具有显式 lambda 的堆栈跟踪添加了这一行:

at com.example.StackTractTest.lambda$0(StackTractTest.java:26)

这是因为 lambda 被 javac 翻译成一个新生成的方法,你可以在堆栈跟踪中实际看到这个新方法是 lambda$0

使用方法引用,不需要生成新方法,因为它直接引用现有方法。

关于java - 使用方法引用与 lambda 时,堆栈跟踪的可导航性是否较低?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33692042/

相关文章:

java - 通过 Java 使用 auth token 发出 api 请求

java - GSON 解析 JSON 数组

python - 将贝塞尔函数与 2 个变量积分

python - 如何在每次迭代中获取 Enum 属性的随机值?

Java - 调用从数组返回整数字符串的方法

java - 目标 org.springframework.boot :spring-boot-maven-plugin:1. 的执行默认值 2.3.RELEASE:repackage failed: Source must reference an existing file

Java流,从2个列表中获取数据

linux - "/usr/bin/javac:/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory"

Java 8 - 如何访问封装为 lambda 的对象和方法

带有 Selenium WebDriver 的 Java8