내가 예를 들어 다음과 같은 프로그램을 고려 자바 (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));
}
}
는, 자바 (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 Interface (JDI)를 사용하여 프로그램의 모든 단계를 인터셉트하려고합니다. 문제가되는 주먹은 λ 클래스에 해당하는 ClassPrepareEvent event
을 처리 할 때입니다. event.referenceType()
에게 질문하면 시원한 Lam$$Lambda$1.1464642111
과 같은 것을 얻을 수 있습니다. 그런 다음 에 .allLineLocations()
을 호출하면 AbsentInformationException
이 발생하며 컴파일 된 파일의 LineNumberTable
과 확연히 구분됩니다.
Java에서 람다 본문을 단계적으로 실행하는 것처럼 보입니다. JDI에서 어떻게 할 수 있는지 아는 사람이 있습니까? 업데이트
:
.allLineLocations
가 Lam
클래스라고
- , 그것은 않습니다 다음 줄 번호를 모두 반영합니다.
- JDI
Event
는 람다 클래스 내에서 발생 (예 : 스테핑에서), 위치의
jdk.internal.org.objectweb.asm.*
는- 가 난 람다 복사와 관련된 물건의 무리를하고있는 것 같습니다 확실하지 바이트 코드에 소스 라인에서지도는 자바에서, 또는에 보관되어있는 경우 JDI
.sourceName()
는를 슬로우
AbsentInformationException
그래서 내 작업 가설은 람다의 클래스가 런타임에 생성 될 때 JDI는 것을 인식 뭔가를 할 필요가 있다는 것입니다 새 클래스의 바이트 코드가 이전 클래스의 바이트 코드에서옵니다 (w hich는 Lam.java
에서 온 것입니다.) 어디서부터 시작해야 할지를 알기 위해 java.lang.Class
또는 com.sun.jdi.ClassType
의 내부 표현에 대해 충분히 알지 못합니다.
이유는이을하려고 오전 :
- 가 Java Visualizer는 람다
이것은 도움이되었고 무슨 일이 일어나고 있는지 다시 생각하게되었습니다. 나는 이전에 "접근 $"방법을 숨기기 위해 사용했던 제목에 "$"가 붙은 방법을 사용하지 않고 목욕탕으로 아기를 던졌습니다. 이제는 그것을 고쳤습니다. http://goo.gl/VwFzIN – daveagp