Java Language
स्टैक-वॉकिंग एपीआई
खोज…
परिचय
जावा 9 से पहले, थ्रेड स्टैक फ्रेम तक पहुंच एक आंतरिक वर्ग sun.reflect.Reflection
तक सीमित थी। विशेष रूप से विधि sun.reflect.Reflection::getCallerClass
। कुछ पुस्तकालय इस पद्धति पर निर्भर करते हैं जो कि पदावनत है।
एक वैकल्पिक मानक एपीआई अब के माध्यम से JDK 9 में प्रदान की जाती है java.lang.StackWalker
वर्ग, और ढेर फ्रेम आलसी पहुँच की अनुमति देकर कुशल होने के लिए बनाया गया है। कुछ एप्लिकेशन इस एपीआई का उपयोग कक्षाओं पर निष्पादन स्टैक और फिल्टर को पार करने के लिए कर सकते हैं।
वर्तमान धागे के सभी स्टैक फ्रेम प्रिंट करें
निम्नलिखित वर्तमान धागे के सभी स्टैक फ्रेमों को प्रिंट करता है:
1 package test;
2
3 import java.lang.StackWalker.StackFrame;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.util.List;
7 import java.util.stream.Collectors;
8
9 public class StackWalkerExample {
10
11 public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
12 Method fooMethod = FooHelper.class.getDeclaredMethod("foo", (Class<?>[])null);
13 fooMethod.invoke(null, (Object[]) null);
14 }
15 }
16
17 class FooHelper {
18 protected static void foo() {
19 BarHelper.bar();
20 }
21 }
22
23 class BarHelper {
24 protected static void bar() {
25 List<StackFrame> stack = StackWalker.getInstance()
26 .walk((s) -> s.collect(Collectors.toList()));
27 for(StackFrame frame : stack) {
28 System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " + frame.getMethodName());
29 }
30 }
31 }
आउटपुट:
test.BarHelper 26 bar
test.FooHelper 19 foo
test.StackWalkerExample 13 main
वर्तमान कॉलर वर्ग प्रिंट करें
निम्नलिखित वर्तमान कॉलर वर्ग को प्रिंट करता है। नोट इस मामले में, कि StackWalker
विकल्प के साथ बनाने की आवश्यकता है RETAIN_CLASS_REFERENCE
, ताकि Class
उदाहरणों बनाए रखा जाता है में StackFrame
वस्तुओं। अन्यथा एक अपवाद होता।
public class StackWalkerExample {
public static void main(String[] args) {
FooHelper.foo();
}
}
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
System.out.println(StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).getCallerClass());
}
}
आउटपुट:
class test.FooHelper
प्रतिबिंब और अन्य छिपे हुए फ्रेम दिखा रहा है
कुछ अन्य विकल्पों में स्टैक के निशान को क्रियान्वयन और / या प्रतिबिंब फ्रेम शामिल करने की अनुमति है। यह डीबगिंग उद्देश्यों के लिए उपयोगी हो सकता है। उदाहरण के लिए, हम निर्माण पर StackWalker
उदाहरण के लिए SHOW_REFLECT_FRAMES
विकल्प जोड़ सकते हैं, ताकि चिंतनशील तरीकों के लिए फ़्रेम भी मुद्रित हों:
package test;
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
public class StackWalkerExample {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method fooMethod = FooHelper.class.getDeclaredMethod("foo", (Class<?>[])null);
fooMethod.invoke(null, (Object[]) null);
}
}
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
// show reflection methods
List<StackFrame> stack = StackWalker.getInstance(Option.SHOW_REFLECT_FRAMES)
.walk((s) -> s.collect(Collectors.toList()));
for(StackFrame frame : stack) {
System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " + frame.getMethodName());
}
}
}
आउटपुट:
test.BarHelper 27 bar
test.FooHelper 20 foo
jdk.internal.reflect.NativeMethodAccessorImpl -2 invoke0
jdk.internal.reflect.NativeMethodAccessorImpl 62 invoke
jdk.internal.reflect.DelegatingMethodAccessorImpl 43 invoke
java.lang.reflect.Method 563 invoke
test.StackWalkerExample 14 main
ध्यान दें कि कुछ प्रतिबिंब विधियों के लिए लाइन नंबर उपलब्ध नहीं हो सकते हैं इसलिए StackFrame.getLineNumber()
नकारात्मक मान लौटा सकता है।