首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java调试接口、Lambdas和行号

Java调试接口、Lambdas和行号
EN

Stack Overflow用户
提问于 2014-03-29 19:34:13
回答 1查看 1.1K关注 0票数 11

我在更新调试器以使用Java 8时遇到了一些问题。

代码语言:javascript
复制
public class Lam {
    public static void main(String[] args) {
        java.util.function.Function<Integer, Integer> square =
            x -> {
            int result = 0;
            for (int i=0;
                 i<x;
                 i++)
                result++;
            return result;
        };
        System.out.println(square.apply(5));
    }
}

正如预期的那样,Java 8将lambda编译成如下所示:

代码语言:javascript
复制
> javap -c -p -v -s -constants Lam
Classfile Lam.class
...
  private static java.lang.Integer lambda$main$0(java.lang.Integer);
...
Code:
  stack=2, locals=3, args_size=1
     0: iconst_0
     1: istore_1
...
LineNumberTable:
    line 5: 0
    line 6: 2
    line 7: 4
    line 9: 12
    line 8: 15
    line 10: 21

这看起来很像普通代码。但是,我试图使用Java调试器接口(JDI)来拦截程序的每一步。出错的第一件事是当我处理与lambda类对应的ClassPrepareEvent event时。询问event.referenceType()会给我一些类似于Lam$$Lambda$1.1464642111的东西,这很酷。但是,在.allLineLocations()上调用.referenceType()会给出一个AbsentInformationException,这似乎与编译文件中的LineNumberTable不一致。

它看起来像是在Java8 是可能的中跨过lambda主体。但是,有谁知道如何在JDI中做到这一点呢?

更新:

  • 当在.allLineLocations类上调用Lam时,它确实反映了所有这些行号。
  • 当在lambda类中发生JDI Event时(例如,从单步执行),位置的.sourceName()抛出一个AbsentInformationException
  • 看起来jdk.internal.org.objectweb.asm.*正在做一些与复制lambda有关的事情
  • 我不确定从源行到字节码的映射是保存在Java中还是在JDI中

因此,我的工作假设是,当在运行时创建lambda类时,JDI需要做一些事情来识别新类的字节码来自旧类的字节码(反过来来自Lam.java)。我对java.lang.Classcom.sun.jdi.ClassType的内部表示不太了解,不知道从哪里开始。

我为什么要这么做

  • 更新Java可视化器以使用lambda
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-31 21:03:25

您似乎混淆了编译后的类和运行时生成的lambda类。后者只包含将函数接口与编译器类lambda方法中的实现连接起来的胶水--这里没有任何您想要通过的东西,可能只是没有源的方法名。因为没有源,所以lambda类没有sourceName。ASM代码正在构建生成的lambda类。从字节码位置到源行的映射在类文件中。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22735872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档