Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Cách lọc stack frame dùng StackWalker API trong Java 9

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

StackWalker API cho phép lọc stack frame hiệu quả, type-safe, lazy – thay thế hoàn toàn Thread.getStackTrace().

OptionMô tả
RETAIN_CLASS_REFERENCEGiữ Class reference cho getDeclaringClass()
SHOW_HIDDEN_FRAMESHiển thị hidden frame (reflection, lambda...)
SHOW_REFLECT_FRAMESHiển thị reflection frame