Java 9 StackWalker API cung cấp laziness và frame filtering. Object StackWalker cho phép duyệt stack, phương thức chính: walk(). Mở Stream<StackFrame> cho thread hiện tại, apply function. Lấy instance qua StackWalker.getInstance().
Ví dụ: In all / skip / limit stack frames
import java.lang.StackWalker.StackFrame;
import java.util.*;
import java.util.stream.*;
public class StackWalkerTest {
public static void main(String args[]) {
new StackWalkerTest().walk();
}
private void walk() {
new Walker1().walk();
}
private class Walker1 {
public void walk() {
new Walker2().walk();
}
}
private class Walker2 {
public void walk() {
Method1();
}
void Method1() { Method2(); }
void Method2() {
StackWalker stackWalker = StackWalker.getInstance(
Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE, StackWalker.Option.SHOW_HIDDEN_FRAMES), 16);
Stream<StackFrame> stackStream = StackWalker.getInstance().walk(f -> f);
System.out.println("--- Walk all StackFrames ---");
List<String> stacks = walkAllStackframes();
System.out.println(stacks);
System.out.println("--- Skip some StackFrames ---");
List<String> stacksAfterSkip = walkSomeStackframes(3);
System.out.println(stacksAfterSkip);
System.out.println("--- Limit StackFrames ---");
List<String> stacksByLimit = walkLimitStackframes(3);
System.out.println(stacksByLimit);
}
private List<String> walkAllStackframes() {
return StackWalker.getInstance().walk(s -> s.map(frame ->
"\n" + frame.getClassName() + "/" + frame.getMethodName()).collect(Collectors.toList()));
}
private List<String> walkSomeStackframes(int numberOfFrames) {
return StackWalker.getInstance().walk(s -> s.map(frame ->
"\n" + frame.getClassName() + "/" + frame.getMethodName()).skip(numberOfFrames).collect(Collectors.toList()));
}
private List<String> walkLimitStackframes(int numberOfFrames) {
return StackWalker.getInstance().walk(s -> s.map(frame ->
"\n" + frame.getClassName() + "/" + frame.getMethodName()).limit(numberOfFrames).collect(Collectors.toList()));
}
}
}
Kết quả
--- Walk all StackFrames --- [ StackWalkerTest$Walker2/walkAllStackframes, StackWalkerTest$Walker2/Method2, StackWalkerTest$Walker2/Method1, StackWalkerTest$Walker2/walk, StackWalkerTest$Walker1/walk, StackWalkerTest/walk, StackWalkerTest/main ] --- Skip some StackFrames --- [ StackWalkerTest$Walker2/walk, StackWalkerTest$Walker1/walk, StackWalkerTest/walk, StackWalkerTest/main ] --- Limit StackFrames --- [ StackWalkerTest$Walker2/walkLimitStackframes, StackWalkerTest$Walker2/Method2, StackWalkerTest$Walker2/Method1 ]
Giải thích
| Phương thức | Stream operation | Kết quả |
|---|---|---|
| walkAllStackframes | .collect(toList()) | Toàn bộ stack (bottom → top) |
| walkSomeStackframes(3) | .skip(3).collect(toList()) | Bỏ 3 frame đầu (top), lấy phần còn lại |
| walkLimitStackframes(3) | .limit(3).collect(toList()) | Chỉ lấy 3 frame đầu (top) |
Ưu điểm StackWalker
- Lazy: Chỉ materialize frame khi stream consume.
- Filterable: Dùng Stream API (
filter, map, skip, limit). - Class reference: Với
RETAIN_CLASS_REFERENCE, lấy đượcClass<?>. - Hidden frames: Có option hiển thị frame ẩn (reflection, lambda, method handle).
- Performance: Tránh allocate array toàn bộ stack trace như
getStackTrace().
StackWalker API là công cụ mạnh cho profiling, logging, diagnostic, error reporting trong Java 9+.