StackWalker API cung cấp stream thông tin stack trace khi thực thi. Yêu cầu VM capture snapshot toàn bộ stack, trả về mảng element để lọc. Sử dụng walk() để skip, drop, limit frame. Lọc frame theo class: frame đầu khớp (findFirst()) hoặc tất cả frame khớp (filter() + collect()).
Ví dụ lọc frame theo class
import java.lang.StackWalker.StackFrame;
import java.util.*;
import java.util.stream.*;
public class StackWalkerFilterTest {
public static void main(String args[]) {
final List<Class> filterClasses = new ArrayList<>();
filterClasses.add(StackWalkerFilterTest.class);
System.out.println("--- filter Frame by Class >> get first matching frame ---");
Optional<StackFrame> frameByClass = findFrameByClass(filterClasses);
System.out.println(frameByClass.toString());
System.out.println("--- filter Frame by Class >> get all matching frames ---");
List<StackFrame> framesByClass = findAllFramesByClass(filterClasses);
System.out.println(framesByClass);
}
private static Optional<StackFrame> findFrameByClass(List<Class> filterClasses) {
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk(s -> s.filter(f -> filterClasses.contains(f.getDeclaringClass())).findFirst());
}
private static List<StackFrame> findAllFramesByClass(List<Class> filterClasses) {
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk(s -> s.filter(f -> filterClasses.contains(f.getDeclaringClass())).collect(Collectors.toList()));
}
}
Kết quả
--- filter Frame by Class >> get first matching frame --- Optional[StackWalkerTest.findFrameByClass(StackWalkerTest.java:20)] --- filter Frame by Class >> get all matching frames --- [StackWalkerTest.findAllFramesByClass(StackWalkerTest.java:23), StackWalkerTest2.main(StackWalkerTest.java:15)]
Giải thích
Option.RETAIN_CLASS_REFERENCE: Cần thiết đểgetDeclaringClass()trả vềClass<?>không null.walk(Function<Stream<StackFrame>, R>): Nhận function xử lý stream frame.filter(f -> filterClasses.contains(f.getDeclaringClass())): Chỉ giữ frame thuộc class trong danh sách.findFirst(): Lấy frame đầu tiên (gần top nhất).collect(Collectors.toList()): Lấy tất cả frame khớp.
Các Option của StackWalker
| Option | Mô tả |
|---|---|
RETAIN_CLASS_REFERENCE | Giữ Class reference cho getDeclaringClass() |
SHOW_HIDDEN_FRAMES | Hiển thị hidden frame (reflection, lambda...) |
SHOW_REFLECT_FRAMES | Hiển thị reflection frame |