Java调试接口,Lambdas和行号

前端之家收集整理的这篇文章主要介绍了Java调试接口,Lambdas和行号前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在更新调试器以使用 Java 8时遇到一些问题.请考虑以下程序,例如:
  1. public class Lam {
  2. public static void main(String[] args) {
  3. java.util.function.Function<Integer,Integer> square =
  4. x -> {
  5. int result = 0;
  6. for (int i=0;
  7. i<x;
  8. i++)
  9. result++;
  10. return result;
  11. };
  12. System.out.println(square.apply(5));
  13. }
  14. }

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

  1. > javap -c -p -v -s -constants Lam
  2. Classfile Lam.class
  3. ...
  4. private static java.lang.Integer lambda$main$0(java.lang.Integer);
  5. ...
  6. Code:
  7. stack=2,locals=3,args_size=1
  8. 0: iconst_0
  9. 1: istore_1
  10. ...
  11. LineNumberTable:
  12. line 5: 0
  13. line 6: 2
  14. line 7: 4
  15. line 9: 12
  16. line 8: 15
  17. 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类.从字节码位置到源行的映射是在类文件中.

猜你在找的Java相关文章