Java Review Notes 5 - Exception Handling

Posted by dvdflashbacks on Thu, 21 Nov 2019 22:47:24 +0100

exception handling

Exception classification and architecture:

Error-related types of exceptions are exceptions that programs cannot handle (most of which are unresolved by modifying code), and these exceptions often require us to adjust the JVM's operating environment

Exception-related types of exceptions are exceptions that programs can handle and contain two subtypes

  • Compile Exception

    Usually it is a syntax error or if the method explicitly indicates that an exception may be thrown it must be caught and handled

  • Runtime Exception

    Exceptions that are not found during the check phase, satisfy all grammar specifications, and can only be found at runtime

exception handling

Keyword try catch finally throws throw

Basic grammar:

Be careful:

  • Trys cannot be used alone and must be combined with catch or finally
  • finally means that ultimately, whether or not the exception actually occurs, the final will be executed

  • Generic exception handling (omnipotent exception handling) when the exception type is Exception, which catches all exceptions but does not target them
  • A try can have more than one catch
  • Usually Exception is added to the last catch as a complete guarantee that the program can continue to run
  • Each exception type can only occur once for all catch es in a try
  • Exception types in catch must be small to large (first subclass in parent class)
  • No matter how many catch es there are, only one will be executed (like if else....)
  • To interrupt finally execution, exit the virtual machine directly, System.exit();

Effect of finally on return

In a method, if there is finally, even if a return statement is encountered in a try or catch, the method does not end immediately, but must finish executing finally before it ends.

Case:

class Test{
  public static void main(String[] args){
        System.out.println(func(0));
    //The result here is 10000;
    //10 if there is no finally;
  }
  public static int func(int arg){
    try{
      int a = 1/arg;
      return a;
    }catch(Exception e){
      return 10;
    }finally{
      return 10000;
    }
  }
}
Emphasis: Regardless of whether an exception occurs or not in the method, the return value is based on the return value in finally, which is not realistic, so it is usually not written as such

throw

throws

Used for method definitions, which can be declared with throws, and methods may throw some type of exception

When to use throws

When there may be exceptions in a method, but the method itself cannot handle them or does not want to handle them.... throws can be used to throw

It should be emphasized that if an exception is thrown and not eventually handled, it will cause the program to interrupt, so we can't generally let it go.

Use

Be careful:

  • Simply put, if declared, it means that the exception will not be handled within the method and that whoever calls it will be handled by whoever.

  • The caller needs to catch the exception and handle it, or continue throwing it up if the caller cannot handle it
  • A method can also declare that it throws many different types of exceptions, and the caller of the response should increase the corresponding catch

Case:

package com.yh.test;

public class Test {
    public static void main(String[] args){
       //The program is terminated if it is thrown all the way to the program entry and not processed
        func3();
    }
    static public void func2() throws ArithmeticException{
        int a = 1/0;
    }

    static public void func3() throws ArithmeticException{
        try{
            func2();//func2 throws an exception
        }catch (Exception e){
           //Unhandled continue throwing up
            throw e;
        }
    }
}

Multiple types of exceptions were thrown:

import java.util.InputMismatchException;
import java.util.Scanner;

public class Test {
    public static void main(String[] args){
        try {
            func3();
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (InputMismatchException e) {
            e.printStackTrace();
        }
    }
    static public int func3() throws ArrayIndexOutOfBoundsException,InputMismatchException{//        try{
            int a = new Scanner(System.in).nextInt();
            return 10/a;
    }
}

throw

Actively throw an exception

Use scenarios:

Exceptions should be thrown proactively when the provider of the method requires the caller to provide some data, but the data is illegal and the functionality cannot be properly handled

Callers can handle exceptions after they have been caught

Throw or process?

Exceptions caused inside methods are handled by themselves, while exceptions caused by callers are thrown (or handled if they can be handled)

Confusion: Why does the compiler require a solution when throws Exception?

Because Exception contains both runtime and compile-time exceptions, it is required that you handle them. Thus, when throws declare exceptions that are compile-time exceptions, you must provide code to handle them.

Case:

package com.yh.test;

public class Test {
    public static void main(String[] args){
        try {
            func(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void func(int a) throws  Exception{
        if (a < 1){
            throw new Exception("Parameter cannot be less than 1");
        }
    }
}

Custom Exception

When built-in exceptions do not satisfy characteristic business scenarios, exception classes can be customized simply by inheriting Exception

Case:

class MyException extends Exception{
    public MyException() {
        super("Fixed exception hints!");
    }
}

Constructors can be defined as above when exception prompt information is fixed

Abnormal Chain

When an exception thrown by a method is caught by the calling method, but the calling method throws a new exception, an exception chain is formed.

If we throw a new exception directly in the calling method without any additional action, the original exception information is lost.

There are two ways we can keep the original exception information

1. Use the original exception as a parameter when instantiating

2. Call initCause after instantiation to pass in the original exception object

Case:

package com.yh.test;

public class ExceptionLinkeTest {
    public static void main(String[] args) {
        try {
            func2();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static public void fun1() throws ArithmeticException{
        int a = 1 / 0;
    }

    static public void func2() throws Exception{
        try{
            fun1();
        }catch (ArithmeticException e){
            //Do not keep the original exception information
            //Throw new Exception ("new exception information!");
          
            //Preserve Exception Information Method 1
            throw  new Exception("New Exception Information!",e);
          
            //Preserve Exception Information Method 2
              Exception newex = new Exception("New Exception Information!");
            newex.initCause(e);
            throw newex;          
        }
    }
}

When we don't handle it, we get the following exception information:

Use method 1 or method 2 to keep exception information as follows:

Topics: Java jvm less