Do you really read Java's exception information?

Source: Internet
Author: User
Tags getmessage print format stack trace wrapper

The following exception information is given:

Java.lang.RuntimeException:level 2 Exceptionat com.msh.demo.exceptionStack.Test.fun2 (test.java:17) at Com.msh.demo.exceptionStack.Test.main (test.java:24) at Sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method ) at Sun.reflect.NativeMethodAccessorImpl.invoke (nativemethodaccessorimpl.java:62) at Sun.reflect.DelegatingMethodAccessorImpl.invoke (delegatingmethodaccessorimpl.java:43) at Java.lang.reflect.Method.invoke (method.java:498) at Com.intellij.rt.execution.application.AppMain.main ( appmain.java:147) caused By:java.io.IOException:level 1 Exceptionat com.msh.demo.exceptionStack.Test.fun1 (Test.java : At Com.msh.demo.exceptionStack.Test.fun2 (test.java:15) ... 6 more

After all these years of studying Java, do you really read Java's exception information? Can you explain the sequence of events in the exception-throwing process?

Write a demo test for the content that needs to be built in

The above exception information is generated by a demo:

Package Com.msh.demo.exceptionstack;import java.io.ioexception;/** * Created by Monkeysayhi on 2017/10/1. */public class Test {  private void fun1 () throws IOException {    throw new IOException ("Level 1 exception");  }  private void Fun2 () {    try {      fun1 ()    } catch (IOException e) {        throw new RuntimeException ("Level 2 exc Eption ", e);    }  }  public static void Main (string[] args) {    try {      new Test (). fun2 ();    } catch (Exception e) {      E.printstac Ktrace ();}}}  

This time I copied the full file content so that the code line number in the article corresponds to the actual line number one by one.

According to the above exception information, the sequence of events in the exception throw process is:

    1. In line 10th of Test.java, a ioexceotion ("Level 1 Exception") was thrown E1
    2. The exception E1 is thrown out of the layer, until the 15th line in Test.java is captured
    3. On line 17th of Test.java, a runtimeexception ("Level 2 Exception", E1) is thrown according to the E1 of the caught exception E2
    4. The exception E2 is thrown out of the layer, until the 24th line in Test.java is captured
    5. Subsequent no additional exception information, after the necessary framework, by the program automatically or the user actively call the E2.printstacktrace () method
How to read exception information

So how do you read the exception information? There are a few things you need to know clearly:

    • The exception stack is printed in filo order, and the exception at the bottom of the print content is first thrown, gradually causing the exception to be thrown. The exception that is at the top of the print content is thrown at the latest, and is no longer captured. From top to bottom, the first i+1 exception is the i reason that the first exception was thrown cause , starting with "caused by".
    • Each exception in the exception stack consists of the exception name + details + path. The exception name starts at the beginning of the line (or immediately after "caused by"), followed by details (for readability, with appropriate details), starting from the next row, skipping a tab, a position in the path, one position at a a-line.
    • The path is printed in FIFO order, and the position at the top of the print content is first passed by the exception and thrown out of the layer. The first passing position is where the exception is thrown, which can be started from here when reverse debugging, and the subsequent location is usually the entrance to the method call, which can be obtained from the method stack when the JVM catches the exception. For cause, its printable path ends before being wrapped in the next exception, and then printing "... 6 more ", which indicates that cause is wrapped as an exception, after which there are 6 positions layered outward, but these positions are duplicated with the path of the wrapper exception, so omitted here and printed in the path of the wrapper exception. “... 6 More "The information is unimportant and can be ignored.

Now, is it quite simple to go back and read the sample exception information?

To help understand, I have described the structure and composition of exception information as easily as possible, and may introduce some flaws. Reading the exception information is the basic skill of the Java program Ape, and hopefully you will be able to put it into your mind and forget these lengthy descriptions.

If you do not understand it, it is recommended that you trace the creation and printing process of the exception yourself, using the sample code, which is simple but sufficient. The difficulty is that the exception is the mechanism provided by the JVM, you need to understand the implementation of the JVM, and the underlying calls a lot of native methods, and tracking native code is not so convenient.

Extension why sometimes I only see the exception name "Java.lang.NullPointerException" in the log, but there is no exception stack

The exception information for the sample, exception name, detail information, path three elements have, however, due to JVM optimization, details and paths may be omitted.

This often occurs in the log of the server application, because the same exception has been printed multiple times, and if you continue to print the same exception, the JVM will omit the details and path queue and scroll forward to find the complete exception information.

Monkey has experienced this problem before using Yarn's timeline server. Can you feel that feeling? Horizontal slot, why is there only exception name without exception stack? No exception stack how does Lao Tzu know where to throw the exception? Online service I can not stop, all by the log ah Hello!

There are many similar case, such as NullPointerException missing exception stack information, the reader can refer to this link to experiment.

How to add a member variable to an exception class

In order to properly express an exception, we sometimes need to customize the exception and add some member variables to print the exception stack and automatically replenish the necessary information when printing.

Trace the code to print the exception stack:

... public void Printstacktrace () {printstacktrace (system.err);    } ... public void Printstacktrace (PrintStream s) {printstacktrace (new Wrappedprintstream (s)); } ... private void Printstacktrace (Printstreamorwriter s) {//Guard against malicious overrides of Throwable.equ        ALS by//using a Set with identity equality semantics.        Set<throwable> Dejavu = Collections.newsetfrommap (New identityhashmap<throwable, Boolean> ());        Dejavu.add (this);            Synchronized (S.lock ()) {//Print our stack trace s.println (this);            Stacktraceelement[] trace = Getourstacktrace ();            for (stacktraceelement traceelement:trace) s.println ("\tat" + traceelement); Print suppressed exceptions, if any for (Throwable se:getsuppressed ()) Se.printenclosedstac            Ktrace (S, Trace, suppressed_caption, "\ T", Dejavu); Print cause, if any           Throwable ourcause = Getcause ();        if (ourcause! = null) Ourcause.printenclosedstacktrace (S, Trace, Cause_caption, "", Dejavu); }    }...

Temporarily do not care about the synchronization problem, we know that the code to print the exception name and details:

S.println (this);

The JVM implements the polymorphic invocation on this reference at run time through dynamic binding. If you continue tracing, the ToString () method of the This instance will eventually be called. The lowest common ancestor class for all exceptions is the Throwable class, which provides the default ToString () implementation, and most common exception classes do not override this implementation, and our custom exceptions can inherit this implementation directly:

...    Public String toString () {        String s = getclass (). GetName ();        String message = Getlocalizedmessage ();        return (Message! = NULL)? (S + ":" + message): s;    } ...    Public String Getlocalizedmessage () {        return getMessage ();    } ...    Public String GetMessage () {        return detailmessage;    } ...

Obviously, the default implementation of the print format is the sample exception Information Format: Exception name (fully qualified name) + detail information. Detailmessage is set when the user creates an exception, so if there are custom member variables, we usually insert this variable in the ToString () method. com.sun.javaws.exceptionsin the reference package BadFieldException , see how it inserts the custom member variable field and value:

Public String toString () {  return This.getvalue (). Equals ("https")? " badfieldexception["+ this.getrealmessage () +"] ":" badfieldexception["+ this.getfield () +", "+ this.getvalue () +"] ";}

Strictly speaking, BadFieldException the ToString does not directly insert the field member variable. However, this does not affect our understanding, interested readers can self-browsing source code.

Summarize

Based on the exception information debug is the basic skills of the programmer, here is the exception information on the reading and printing process to make a preliminary exploration, the following will also tidy up the common exception class, better understand how to use the exception to help us write clean code.

Java is a fairly complete exception handling mechanism is a double-edged sword, with good it can enhance the readability and robustness of the code, using the bad will make the code become more uncontrolled. For example, invoking a member method on a null pointer, the runtime throws an exception, is natural-but is it not controlled to wait for it to throw an exception at some point in time (actually "OK", but for debug), or is it controllable to check and throw an exception at the beginning of the entry method? Further, which anomalies should be dealt with immediately, and which should continue to be thrown into the outer layers? When you throw the outer layer, when do you need to encapsulate the exception? Look at String#tolowercase (), see Processbuilder#start (), and experience.

Java Learning Exchange QQ Group: 589809992 prohibit small talk, non-happy do not enter!

Do you really read Java's exception information?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.