我在更新调试器以使用
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与羊羔一起工作