使用Java新功能StackWalker
StackWalking API是最近新增到Java中的最酷功能之一
在Java9之前,要獲得棧資訊辦法是:獲取當前執行緒並呼叫其getStackTrace()方法
另一個智慧解決方案涉及...丟擲異常並從中提取堆疊跟蹤資訊。但是,無法操縱結果,它只會立即輸出:
兩種解決方案都存在同樣的問題 - 它們只是捕獲了整個堆疊的快照,並且不方便使用。
還可以定製一點初始化資訊:
如果我們想要遍歷整個堆疊,只需呼叫forEach()方法:
如果我們檢視Java 1.4的StackTraceElement - 它幾乎是一個包含有關宣告類,方法名,類載入器名等的字串資訊的DTO。
StackWalker.StackFrame是一個更加型別安全友好的升級,豐富了以下方法:
public Class<?> getDeclaringClass();
public MethodType getMethodType();
public StackTraceElement toStackTraceElement();
讓我們將其付諸實踐並建立一個簡單的呼叫層次結構:
執行這段程式碼獲得:
使用基於Function介面的模板方法是有意義的:當呼叫walk()方法時,堆疊需要被凍結才能遍歷它。
我們可以優雅地跳過一些frame,並選擇第一個遇到的frame:
在Java9之前,要獲得棧資訊辦法是:獲取當前執行緒並呼叫其getStackTrace()方法
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); <p class="indent"> |
另一個智慧解決方案涉及...丟擲異常並從中提取堆疊跟蹤資訊。但是,無法操縱結果,它只會立即輸出:
new Exception().printStackTrace(); <p class="indent"> |
兩種解決方案都存在同樣的問題 - 它們只是捕獲了整個堆疊的快照,並且不方便使用。
JEP-259提出Stack-Walking API可以解決這些問題。新的API提供了一種使用Stream API惰性地遍歷堆疊跟蹤的便捷方法。
我們可以像以下一樣輕鬆建立StackWalker例項:
StackWalker stack = StackWalker.getInstance(); <p class="indent"> |
還可以定製一點初始化資訊:
StackWalker stack = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); <p class="indent"> |
如果我們想要遍歷整個堆疊,只需呼叫forEach()方法:
stack.forEach(System.out::println); <p class="indent"> |
如果我們檢視Java 1.4的StackTraceElement - 它幾乎是一個包含有關宣告類,方法名,類載入器名等的字串資訊的DTO。
StackWalker.StackFrame是一個更加型別安全友好的升級,豐富了以下方法:
public Class<?> getDeclaringClass();
public MethodType getMethodType();
public StackTraceElement toStackTraceElement();
讓我們將其付諸實踐並建立一個簡單的呼叫層次結構:
public static void main(String[] args) { foo(); } private static void foo() { bar(); } private static void bar() { java.lang.StackWalker .getInstance(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE) .forEach(System.out::println); } <p class="indent"> |
執行這段程式碼獲得:
com.pivovarit.stack.StackWalker.bar(StackWalker.java:16) com.pivovarit.stack.StackWalker.foo(StackWalker.java:10) com.pivovarit.stack.StackWalker.main(StackWalker.java:6) <p class="indent"> |
高階功能
如果我們想利用懶載入或frame過濾,我們可以使用另一個名為walk()的專用API方法,它允許我們使用Stream API來方便地遍歷堆疊。在閱讀本文時,您可能想象walk()方法只是返回一個Stream例項 - 嗯,事實並非如此。
這個方法實際是:
public <T> T walk(Function<? super Stream<StackFrame>, ? extends T> function) <p class="indent"> |
使用基於Function介面的模板方法是有意義的:當呼叫walk()方法時,堆疊需要被凍結才能遍歷它。
我們可以優雅地跳過一些frame,並選擇第一個遇到的frame:
java.lang.StackWalker .getInstance(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE) .walk(s -> s.skip(1).limit(1).collect(Collectors.toList())) .forEach(System.out::println); // result com.pivovarit.stack.StackWalker.foo(StackWalker.java:12) <p class="indent"> |
相關文章
- Java 18 新功能介紹Java
- Java 16 新功能介紹Java
- Java 20 新功能介紹Java
- Java 8 後的新功能梳理Java
- Java 20中有哪些新功能? - symflowerJava
- Java 17 新功能介紹(LTS)Java
- Java 23:新功能正式公佈Java
- JDK 16:Java 16的新功能 - InfoWorldJDKJava
- JDK 19:Java 19五個新功能 - infoworldJDKJava
- 超詳細 Java 15 新功能介紹Java
- Java 12版本完整指南新功能 | Henn IdanJava
- HHDESK新功能釋出,歡迎大家使用
- 十分鐘內瞭解Java 8到Java 15的新功能 - DEVJavadev
- Java 9 新功能解讀之 HTTP2 和 REPLJavaHTTP
- Gmail新功能:提醒使用者可疑的黑客活動AI黑客
- Java11中的新功能和API詳解系列1JavaAPI
- Java 框架:Spring Boot 2.6健康檢查帶來新功能Java框架Spring Boot
- 【Android】使用Bugly快速接入Tinker熱更新功能Android
- 自JDK 8 以來所有Java和JVM新功能的分類列表JDKJavaJVM
- JAVA8給我帶了什麼——並流行和介面新功能Java
- 【JAVA】java使用Java
- PLSQL Language Reference-PL/SQL新功能-版本11.1 新功能SQL
- PLSQL Language Reference-PL/SQL新功能-版本11.2.0.1新功能SQL
- PLSQL Language Reference-PL/SQL新功能-版本11.2.0.2新功能SQL
- 5 個 CSS 新功能CSS
- C# 3.0新功能C#
- Nodejs 的新功能NodeJS
- ENVI6.1新功能
- PDM2022新功能—使用者介面的優化優化
- 12個蘋果iOS 12新功能彙總!iOS12新功能有哪些?蘋果iOS
- Xcode9 新功能XCode
- iOS 8新功能彙總iOS
- iOS 8新功能總結iOS
- 圖靈社群2.1:新功能圖靈
- 圖靈社群2.0:新功能圖靈
- Spring Security 6.3 新功能Spring
- 深入瞭解蘋果iOS12新功能:語音備忘錄使用教程蘋果iOS
- win10系統有哪些新功能 win10系統新功能介紹Win10