Java调试接口,Lambdas和行号

前端之家收集整理的这篇文章主要介绍了Java调试接口,Lambdas和行号前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在更新调试器以使用 Java 8时遇到一些问题.请考虑以下程序,例如:
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编译成如下所示:

> 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.referenceType()给我一些像Lam $$Lambda $1.1464642111这是很酷.但是,然后在.referenceType()上调用.allLineLocations()给出一个AbsentInformationException,这似乎与编译文件中的LineNumberTable不一致.

它看起来像在Java 8 is possible中跨越lambda体.但是有没有人知道如何在JDI中完成?

更新:

>当在Lam类上调用.allLineLocations时,它会反映所有这些行号.
>当JDI事件发生在lambda类内(例如从步进)时,位置的.sourceName()将抛出一个AbsentInformationException
>它看起来像jdk.internal.org.objectweb.asm.*正在做一些与复制lambda相关的东西
>我不知道从源代码行到字节码的地图是否保存在Java或JDI中

所以我的工作假设是当在运行时创建lambda类时,JDI需要做一些事情来认识到新类的字节码来自旧类的字节码(这又来自于Lam.java).我不知道java.lang.Class或com.sun.jdi.ClassType的内部表示,以知道从哪里开始.

为什么我试图这样做:

>更新Java Visualizer与羊羔一起工作

解决方法

您似乎将编译的类与运行时生成的lambda类混淆.后者仅包含将功能界面与编译器类lambda方法中的实现相连接的粘合剂 – 您没有任何要在其中进行任何操作的东西,可能的例外是只有没有源的方法名称. lambda类没有sourceName,因为没有源. ASM代码正在构建生成的lambda类.从字节码位置到源行的映射是在类文件中.
原文链接:https://www.f2er.com/java/123131.html

猜你在找的Java相关文章