У меня возникают проблемы с обновлением отладчика для работы с 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 компилирует лямбда для чего-то вроде этого:
> 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 Debugger (JDI) для перехвата каждого шага программы. Первая вещь, которая идет не так, - это когда я обрабатываю ClassPrepareEvent event
, соответствующий классу лямбда. Просить event.referenceType()
дает мне что-то вроде Lam$$Lambda$1.1464642111
, которое круто. Но затем вызов .allLineLocations()
в .referenceType()
дает AbsentInformationException
, что, по-видимому, противоречит LineNumberTable
в скомпилированном файле.
Похоже, что перешагнуть лямбда-тела в Java 8 возможно. Но кто-нибудь знает, как это можно сделать в JDI?
Обновления:
- когда
.allLineLocations
вызывается в классеLam
, он отражает все эти номера строк. - когда JDI
Event
происходит в классе лямбда (например, от шага),.sourceName()
местоположения выбрасываетAbsentInformationException
- похоже, что
jdk.internal.org.objectweb.asm.*
делает кучу вещей, связанных с копированием лямбда - Я не уверен, сохранена ли карта из исходных строк в байт-коды в Java или в JDI
Итак, моя рабочая гипотеза заключается в том, что когда класс lambda создается во время выполнения, JDI должен что-то сделать, чтобы признать, что новый байт-код класса происходит из старого байт-кода класса (который, в свою очередь, исходит от Lam.java
), Я не знаю достаточно о внутреннем представлении java.lang.Class
или com.sun.jdi.ClassType
, чтобы знать, с чего начать.
Почему я пытаюсь это сделать:
- обновить Java Visualizer для работы с lambdas