1. Methods for printing stack tracks
Actively call one of the Throwable object's printStackTrace()=printStackTrace(System.err), printStackTrace(PrintStream), and printStackTrace(PrintWriter).
If an Exception is not processed, throws directly after the main method, the exception printStackTrace() method will be called before the program exits, and ultimately Exception in thread "main" + printStackTrace()
2. Stack Track
1. printStackTrace()
First of all, it is necessary to clarify that this method does not come from the Exception class. Except for defining several constructors, all methods are inherited from their parent class. The methods related to exceptions are inherited from the java.lang.Throwable class. printStackTrace() is one of them.
This method prints the stack track information of the Throwable object to the standard error output stream. The output looks like this:
java.lang.NullPointerException at MyClass.mash(MyClass.java:9) at MyClass.crunch(MyClass.java:6) at MyClass.main(MyClass.java:3)
The first line of output is the output of the toString() method. The contents of the following lines are the contents saved previously through the fillInStackTrace() method. We will talk about this method later.
Let's see an example below:
public class TestPrintStackTrace { public static void f() throws Exception{ throw new Exception("There is something wrong!"); } public static void g() throws Exception { f(); } public static void main(String[] args) { try { g(); }catch(Exception e) { e.printStackTrace(); } }}The output of this example is as follows:
java.lang.Exception: Something went wrong! at TestPrintStackTrace.f(TestPrintStackTrace.java:3) at TestPrintStackTrace.g(TestPrintStackTrace.java:6) at TestPrintStackTrace.main(TestPrintStack Trace.java:10)
In this example, an exception is thrown in method f(), a method f() is called in method g(), an exception is caught in main method, and a stack track information is printed. Therefore, the output shows the process of f―>g―>main in turn.
2. getStackTrace() method
This method provides programmatic access to the information printed by the printStackTrace() method. It returns an array of stack track elements. The above output is an example. The content of each line 2-4 output corresponds to a stack track element. Save these stack track elements in an array. Each element corresponds to a stack frame. The first element of the array saves the top element of the stack, which is the f above. The bottom element of the last element saved.
Here is an example of using getStackTrace() to access these track stack elements and print out the output:
public class TestPrintStackTrace { public static void f() throws Exception{ throw new Exception("There is something wrong!"); } public static void g() throws Exception { f(); } public static void main(String[] args) { try { g(); }catch(Exception e) { e.printStackTrace(); System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --------"); for(StackTraceElement elem : e.getStackTrace()) { System.out.println(elem); } } }}Such output is basically the same as printStackTrace()'s output, as follows:
java.lang.Exception: Something went wrong! at TestPrintStackTrace.f(TestPrintStackTrace.java:3) at TestPrintStackTrace.g(TestPrintStackTrace.java:6) at TestPrintStackTrace.main(TestPrintStack Trace.java:10)TestPrintStackTrace.f(TestPrintStackTrace.java:3)TestPrintStackTrace.g(TestPrintStackTrace.java :6)TestPrintStackTrace.main(TestPrintStackTrace.java:10)
Three.fillInStackTrace method
The native fillInStackTrace() method will return a Throwable object, which is created by filling the current call stack information into the original exception object, so the returned original exception is still the original exception.
The line that calls this method will become the exception new location, and information about the original exception occurrence point will be lost. Its effect is equivalent to catching an exception and re-throwing another exception. The difference between the two is that the exception after fillInStackTrace is still the original exception (just lacks the stack track); if an exception is thrown again, it has nothing to do with the original exception information (of course there is no stack track).
package com.jyz.study.jdk.exception; /** * Stack Track* fillInStackTrace * @author [email protected] * */ public class FillInStackTrace { publ ic static void main(String[] args) throws Exception { test1() ; } private static void test1() throws Exception{ try{ test2(); }catch(NullPointerException ex){ //1 throw (Exception)ex.fillInStackTrace(); // 2 throw new Exception(); } } private static void test2(){ test3(); } private static void test3(){ throw new NullPointerException("str is null"); } }
The exception stack information of 1 and 2 is shown in the figure:
The difference is the information of this itself. The first line of the console prints this.
1's stack information
Exception in thread "main" java.lang.NullPointerException: str is null at com.jyz.study.jdk.exception.FillInStackTrace.test1(FillInStackTrace.java:2 0) at com.jyz.study.jdk.exception.FillInStackTrace.main (FillInStackTrace.java:13)
2 stack information
Exception in thread "main" java.lang.Exception at com.jyz.study.jdk.exception.FillInStackTrace.test1(FillInStackTrace.java:21) at com.jyz.study.jdk .exception.FillInStackTrace.main(FillInStackTrace.java :13)