Java 9 StackWalker API란?
StackWalker API는 Java 9에서 새롭게 도입된 기능으로, 메서드 내에서 작업을 수행할 때 손쉽게 필터링하고 지연(lazy) 방식으로 접근할 수 있도록 지원합니다. 스택 트레이스(stack trace) 정보를 효율적으로 얻을 수 있도록 설계된 API입니다.
기존에는 Thread.getStackTrace()나 Throwable.getStackTrace()를 통해 전체 스택 프레임을 배열로 받아야 했지만, StackWalker API는 필요한 프레임만 선택적으로 탐색할 수 있어 성능 면에서 큰 이점을 제공합니다.
StackWalker API에는 세 가지 핵심 클래스가 있습니다.
- StackWalker
- StackWalker.StackFrame
- StackWalker.Option
1. StackWalker
StackWalker API의 메인 클래스입니다. 주요 메서드는 다음과 같습니다.
- walk(): 스택 트레이스를 순회하며 스택 프레임 스트림에 함수를 적용합니다. 가장 많이 사용되는 메서드입니다.
- forEach(): 각 스택 프레임을 순차적으로 탐색합니다.
- getCallerClass(): 호출자(caller) 클래스를 효율적인 방식으로 반환합니다.
2. StackWalker.StackFrame
StackWalker의 정적 중첩 클래스(static nested class)로, StackWalker가 반환하는 메서드 호출 정보를 나타냅니다. 특정 스택 프레임의 정보에 접근할 수 있는 다양한 메서드를 제공합니다.
- getDeclaringClass(): 해당 프레임의 선언 클래스를 반환합니다.
- getLineNumber(): 해당 프레임의 라인 번호를 반환합니다.
- 그 외 getClassName(), getMethodName(), getByteCodeIndex() 등의 메서드도 제공됩니다.
3. StackWalker.Option
StackWalker의 정적 중첩 클래스로, StackWalker.getInstance()를 통해 인스턴스를 생성할 때 스택 프레임 정보를 구성하기 위한 옵션을 지정합니다. 대표적인 옵션으로는 리플렉션 및 익명 클래스 관련 프레임 유지 여부를 결정하는 RETAIN_CLASS_REFERENCE, SHOW_HIDDEN_FRAMES 등이 있습니다.
사용 예제
import java.util.List;
import java.util.stream.Collectors;
public class StackWalkingTest {
public static void main(String args[]) {
final List<StackWalker.StackFrame> stack = StackWalker.getInstance()
.walk(s -> s.collect(Collectors.toList()));
for(StackWalker.StackFrame sf : stack) {
System.out.println(sf.getClassName() + "::" + sf.getMethodName() + ":" + sf.getLineNumber());
}
}
}실행 결과
StackWalkingTest::main:6
위 예제에서는 walk() 메서드를 사용해 현재 스택의 모든 프레임을 리스트로 수집한 뒤, 각 프레임의 클래스 이름, 메서드 이름, 라인 번호를 출력합니다. 이처럼 StackWalker API를 활용하면 불필요한 전체 스택 생성 없이 원하는 스택 정보만 효율적으로 가져올 수 있습니다.