"Think in Java" Reading Notes Volume 3

Handling errors with exceptions

Exception: A problem that prevents the current method or scope from continuing to execute.

Monitoring area: A code area that may generate exceptions, namely the try area.

Exception handler: The place where exceptions are handled, that is, the catch area.

Two models of exception handling

Termination model: Once an exception is thrown, there is no way to return to the place where the exception occurred.

Recovery model: instead of throwing an exception when an exception is raised, patch the exception through a method or by putting a try in a loop.

Note: Restoring the model tends to enhance program coupling

custom exception

import java.util.logging.Logger;

public class MyException {
    private static void f() throws CustomException{
        System.out.println("f:");
        throw new CustomException();
    }
    private static void g(String msg)throws  CustomException{
        System.out.println("g:");
        throw new CustomException(msg);
    }
    private static void h(){
        int x,y,z;
        x=4;
        y=0;
        try {
            z=x/y;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String... args) {
        try {
            f();
        } catch (CustomException e) {

            e.printStackTrace(System.out);
        }
        try {
            g("msg");
        } catch (CustomException e) {
            e.printStackTrace(System.out);
        }
        h();
    }
}
class CustomException extends Exception{
    private Logger logger=Logger.getLogger("CustomException");
    public CustomException(){
    }
    public CustomException(String msg){
        super(msg);
    }

    @Override
    public String getMessage() {
        //return super.getMessage();
        return "This is my custom error info";
    }
}

When commenting out return super.getMessage():

f:
thinkinjava.CustomException: This is my custom error info
at thinkinjava.MyException.f(MyException.java:7)
at thinkinjava.MyException.main(MyException.java:26)
g:
thinkinjava.CustomException: This is my custom error info
at thinkinjava.MyException.g(MyException.java:11)
at thinkinjava.MyException.main(MyException.java:32)
h:
java.lang.ArithmeticException: / by zero
at thinkinjava.MyException.h(MyException.java:19)
at thinkinjava.MyException.main(MyException.java:36)

When commented out return "This is my custom error info":

f:
thinkinjava.CustomException
at thinkinjava.MyException.f(MyException.java:7)
at thinkinjava.MyException.main(MyException.java:26)
g:
thinkinjava.CustomException: msg
at thinkinjava.MyException.g(MyException.java:11)
at thinkinjava.MyException.main(MyException.java:32)
h:
java.lang.ArithmeticException: / by zero
at thinkinjava.MyException.h(MyException.java:19)
at thinkinjava.MyException.main(MyException.java:36)

getMessage is similar to toString method

exception and logging

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Logger;

public class LoggerException {
    private static  Logger logger=Logger.getLogger("LoggerException");
    private static void logprint(Exception e){
        StringWriter sw=new StringWriter();
        PrintWriter pw=new PrintWriter(sw);
        e.printStackTrace(pw);
        logger.severe(pw.toString());
    }
    public static void main(String...args){
        try {
            throw new NullPointerException();
        } catch (NullPointerException e) {
            logprint(e);
        }
    }
}

May 01, 2018 9:31:36 PM thinkinjava.LoggerException logprint
critical: java.io.PrintWriter@330bedb4

throw: throw an error to the upper layer for processing

public class Thrower {
    static void demoproc() {
        try {
            throw new NullPointerException("demo");
        } catch(NullPointerException e) {
            System.out.println("Caught inside demoproc.");
            throw e;
        }
    }
    public static void main(String args[]) {
        try {
            demoproc();
        } catch(NullPointerException e) {
            System.out.println("Recaught: " + e);
        }
    }
}

Caught inside demoproc.
Recaught: java.lang.NullPointerException: demo

stack trace

public class StackTracer {
    private static void a(){
        try{
            throw new Exception();
        }catch (Exception e){
            for(StackTraceElement stackTraceElement:e.getStackTrace())
                System.out.println(stackTraceElement.getMethodName());
        }
    }
    private static void b(){
       a();
    }
    private static void c(){
        b();
    }
    public static void main(String...args){
        a();
        System.out.println("-------------");
        b();
        System.out.println("-------------");
        c();

    }
}

output:

a
main
-------------
a
b
main
-------------
a
b
c
main

Call from the bottom of the stack, similar to recursion

If the current exception is rethrown, printStackTrace() still displays the call stack information of the original exception throw point
    private static void  d() throws Exception{
        throw new Exception("throw new Exception from d");
    }

    private static void e() throws Exception{
        try{
            d();
        }catch (Exception e){
            System.out.println("e try catch");
            e.printStackTrace(System.out);
            throw e;
        }
    }

    private static void f() throws Exception{
        try{
            d();
        }catch (Exception e){
            System.out.println("f try catch");
            e.printStackTrace(System.out);
            throw (Exception) e.fillInStackTrace();
        }
    }
    public static void main(String...args){
        try {
            e();
        }catch (Exception e){
            System.out.println("main try catch from e");
            e.printStackTrace(System.out);
        }
        try {
            f();
        }catch (Exception e){
            System.out.println("main try catch from f");
            e.printStackTrace(System.out);
        }
    }

e try catch
java.lang.Exception: throw new Exception from d
at thinkinjava.StackTracer.d(StackTracer.java:19)
at thinkinjava.StackTracer.e(StackTracer.java:24)
at thinkinjava.StackTracer.main(StackTracer.java:44)
main try catch from e
java.lang.Exception: throw new Exception from d
at thinkinjava.StackTracer.d(StackTracer.java:19)
at thinkinjava.StackTracer.e(StackTracer.java:24)
at thinkinjava.StackTracer.main(StackTracer.java:44)
f try catch
java.lang.Exception: throw new Exception from d
at thinkinjava.StackTracer.d(StackTracer.java:19)
at thinkinjava.StackTracer.f(StackTracer.java:34)
at thinkinjava.StackTracer.main(StackTracer.java:51)
*main try catch from f
java.lang.Exception: throw new Exception from d
at thinkinjava.StackTracer.f(StackTracer.java:38)
at thinkinjava.StackTracer.main(StackTracer.java:51)

Such as the last output result, it no longer outputs the original throw point d

If two different custom exceptions are thrown, they cannot be associated, that is, the stack trace printed at the second throw point will not have any information about the first time. This is if we also want to print the first time. For the stack trace of the throw point, you need to use the exception chain:

public class ExceptionLink {
    class MyException2 extends Exception{
        public MyException2(Throwable throwable){
            super(throwable);
        }
        public MyException2(){
            super();
        }
    }
    class MyException1 extends Exception{
        public  MyException1(){
            super();
        }
    }
    private void a() throws MyException1{
        throw new MyException1();
    }
    private  void b() throws MyException2{
        try {
            a();
        }catch (MyException1 exception1){
            System.out.println("b try catch");
            exception1.printStackTrace(System.out);
            throw new MyException2();
            //throw new MyException2(exception1);
        }
    }
    public static void main(String...args){
        ExceptionLink exceptionLink=new ExceptionLink();
        try {
            exceptionLink.b();
        } catch (MyException2 myException2) {
            System.out.println("main try catch");
            myException2.printStackTrace(System.out);
        }
    }
}

output:

b try catch
thinkinjava.ExceptionLink$MyException1
    at thinkinjava.ExceptionLink.a(ExceptionLink.java:18)
    at thinkinjava.ExceptionLink.b(ExceptionLink.java:22)
    at thinkinjava.ExceptionLink.main(ExceptionLink.java:32)
main try catch
thinkinjava.ExceptionLink$MyException2
    at thinkinjava.ExceptionLink.b(ExceptionLink.java:26)
    at thinkinjava.ExceptionLink.main(ExceptionLink.java:32)

As above, the second throw point does not throw the information thrown by the first throw point, because these are two different exception classes.
If uncomment the commented line, it will output:

b try catch
thinkinjava.ExceptionLink$MyException1
    at thinkinjava.ExceptionLink.a(ExceptionLink.java:18)
    at thinkinjava.ExceptionLink.b(ExceptionLink.java:22)
    at thinkinjava.ExceptionLink.main(ExceptionLink.java:32)
main try catch
thinkinjava.ExceptionLink$MyException2: thinkinjava.ExceptionLink$MyException1
    at thinkinjava.ExceptionLink.b(ExceptionLink.java:26)
    at thinkinjava.ExceptionLink.main(ExceptionLink.java:32)
Caused by: thinkinjava.ExceptionLink$MyException1
    at thinkinjava.ExceptionLink.a(ExceptionLink.java:18)
    at thinkinjava.ExceptionLink.b(ExceptionLink.java:22)
    ... 1 more

This is the exception chain

The finally statement is used in the return statement
try{
    return;
}finally{
    System.out.println("before return")
}

It will print "before return" before returning

Abnormal loss

There are two situations that cause abnormal loss:

try{
    throw new Exception1();
}finally{
    throw new Exception2();
}
try{
    throw new MyException();
}finally{
    return;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325622939&siteId=291194637