Computer >> Máy Tính >  >> Lập trình >> Java

Làm cách nào để in các khung ngăn xếp khác nhau bằng cách sử dụng API StackWalker trong Java?


Java 9 định nghĩa StackWalker API cung cấp sự lười biếng và lọc khung hình. Một đối tượng của StackWalker cho phép chúng tôi duyệt và truy cập các ngăn xếp và chứa một phương thức hữu ích: walk () . Phương thức này sẽ mở ra một StackFrame luồng cho chuỗi hiện tại, sau đó áp dụng chức năng với StackFrame đó dòng. Chúng tôi cần tải StackWalker đối tượng, sau đó sử dụng StackWalker.getInstance () phương pháp.

Trong ví dụ dưới đây, chúng tôi có thể in các khung xếp chồng khác nhau: tất cả xếp chồng khung, bỏ qua một số khung ngăn xếp và giới hạn xếp chồng khung bằng cách sử dụng StackWalker API.

Ví dụ

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())); 
      }
   }
}

Đầu ra

--- 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
]