Java Language
스택 워킹 API
수색…
소개
Java 9 이전에는 스레드 스택 프레임에 대한 액세스가 내부 클래스 sun.reflect.Reflection
으로 제한되었습니다. 특히 sun.reflect.Reflection::getCallerClass
메소드. 일부 라이브러리는이 메소드 대신에 사용되지 않습니다.
또 다른 표준 API는 이제 통해 JDK (9)에서 제공 java.lang.StackWalker
클래스 및 스택 프레임에 게으른 접근을 허용함으로써 효율적으로 설계되어 있습니다. 일부 응용 프로그램은이 API를 사용하여 클래스의 실행 스택과 필터를 트래버스 할 수 있습니다.
현재 스레드의 모든 스택 프레임 인쇄
다음은 현재 스레드의 모든 스택 프레임을 인쇄합니다.
1 package test;
2
3 import java.lang.StackWalker.StackFrame;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.util.List;
7 import java.util.stream.Collectors;
8
9 public class StackWalkerExample {
10
11 public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
12 Method fooMethod = FooHelper.class.getDeclaredMethod("foo", (Class<?>[])null);
13 fooMethod.invoke(null, (Object[]) null);
14 }
15 }
16
17 class FooHelper {
18 protected static void foo() {
19 BarHelper.bar();
20 }
21 }
22
23 class BarHelper {
24 protected static void bar() {
25 List<StackFrame> stack = StackWalker.getInstance()
26 .walk((s) -> s.collect(Collectors.toList()));
27 for(StackFrame frame : stack) {
28 System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " + frame.getMethodName());
29 }
30 }
31 }
산출:
test.BarHelper 26 bar
test.FooHelper 19 foo
test.StackWalkerExample 13 main
현재 호출자 클래스 인쇄
다음은 현재 호출자 클래스를 인쇄합니다. 이 경우, StackWalker
는 RETAIN_CLASS_REFERENCE
옵션으로 생성되어야하므로 Class
인스턴스는 StackFrame
객체에 유지됩니다. 그렇지 않으면 예외가 발생합니다.
public class StackWalkerExample {
public static void main(String[] args) {
FooHelper.foo();
}
}
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
System.out.println(StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).getCallerClass());
}
}
산출:
class test.FooHelper
반사 및 기타 숨겨진 프레임 표시
몇 가지 다른 옵션은 스택 트레이스가 구현 및 / 또는 반사 프레임을 포함 할 수 있도록합니다. 디버깅 목적으로 유용 할 수 있습니다. 예를 들어, 생성시 StackWalker
인스턴스에 SHOW_REFLECT_FRAMES
옵션을 추가하여 반사 방식의 프레임도 인쇄 할 수 있습니다.
package test;
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
public class StackWalkerExample {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method fooMethod = FooHelper.class.getDeclaredMethod("foo", (Class<?>[])null);
fooMethod.invoke(null, (Object[]) null);
}
}
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
// show reflection methods
List<StackFrame> stack = StackWalker.getInstance(Option.SHOW_REFLECT_FRAMES)
.walk((s) -> s.collect(Collectors.toList()));
for(StackFrame frame : stack) {
System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " + frame.getMethodName());
}
}
}
산출:
test.BarHelper 27 bar
test.FooHelper 20 foo
jdk.internal.reflect.NativeMethodAccessorImpl -2 invoke0
jdk.internal.reflect.NativeMethodAccessorImpl 62 invoke
jdk.internal.reflect.DelegatingMethodAccessorImpl 43 invoke
java.lang.reflect.Method 563 invoke
test.StackWalkerExample 14 main
일부 반사 방법의 행 번호는 사용할 수 없으므로 StackFrame.getLineNumber()
가 음수 값을 반환 할 수 있습니다.
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow