Fundamentals: in depth analysis of JAVA exceptions

  • When an exception occurs in the method, an exception object will be created and handed over to the JVM for processing. The exception object contains the exception name, exception description and the state of the application when the exception occurs. The process of creating an exception object and handing it to the JVM is called throwing an exception. There will be a series of method calls, and the ordered list of these method calls is called the call stack
  • The JVM will look up the call stack to see if there is any code that can handle exceptions. When the JVM finds the code that can handle exceptions, it will pass the exceptions to it. If the JVM does not find a code block that can handle the exception, the JVM will transfer the exception to the default exception handler, which will print the exception information

1. Classification and inheritance of exceptions

  • Throwable is a superclass for all errors and exceptions in the Java language. Throwable contains two subclasses: error and exception
  • Errors cannot be handled in the program. These errors are unchecked exceptions and non code errors. Therefore, when such errors occur, the program should not deal with such errors. By convention, we should not implement any new Error subclass
  • An Exception is an Exception that the program itself can catch and handle. Exceptions are divided into two categories: runtime exceptions and compile time exceptions

2 Analysis of several common exception classes

  • RuntimeException (unchecked exception) is a superclass that Java throws an exception during the running of the virtual machine. Any subclass of runtimeException thrown during method execution does not need to be declared in the throws clause because it is uncheckedexcepton. There are five common runtimeexceptions
    • java. Lang. arithmeticexception (arithmetic exception)
    • java. Lang. ClassCastException (type conversion exception)
    • java. Lang. illegalargumentexception (illegal parameter exception)
    • java. Lang. indexoutofboundsexception (array index out of bounds exception)
    • java. Lang.nullpointerexception (null pointer exception)
  • Checked Exception definition: exceptions in Exception except RuntimeException and its subclasses. Features: the Java compiler requires that the program must catch or declare to throw this Exception
    • java.io.IOException(IO stream exception)
    • java. Lang. classnotfoundexception (exception of specified class not found)
    • java. Lang. nosuchfieldexception (exception of specified field not found)
    • java. Lang. nosuchmetodexception (specified method exception not found)
    • java. Lang. illegalaccessexception (illegal access exception)
    • java. Lang. interruptedexception (interrupt exception)

3 Java exception keyword

keyword Function description
try{ } The code that may throw an exception is placed in the try statement block. When an exception occurs in the try statement block, the exception will be thrown
catch(e) Capture exception e; catch is used to catch exceptions in the try statement block. You can declare multiple catches and catch multiple exceptions in catch
finally finally statement blocks are always executed. It is mainly used to recycle the resources opened in the try code block (such as database connection, TCP connection and file stream)
throw Used to throw an exception
throws Declare the exceptions that the method may throw
  • Note: before executing the return and throw statements of try, catch or other places, you need to execute the code in finally. If there are return and throw statements in finally, the method ends after executing the return or throw statements in finally
public int hello(String fileName) throws RuntimeException{
	int a = 10;
    try{
        File file = new File(fileName);
        FileInputStream in = new FileInputStream(file);
        return a; // Return value 10
    }catch (FileNotFoundException e){
        System.out.println("error occurred");
    }catch (ArithmeticException | IndexOutOfBoundsException e){
        System.out.println("whatever");
    } finally{
        System.out.println("finally");
        a = 20; // finally, modifying a will not change the outcome of return 10 in try
        // return a; // If returned here, the return value is equal to 20
    }
    return -1;
}

4. Precautions for handling exceptions in the development process

  • Throw an explicit exception and document the exception
    • If there is an exception in the method that needs to be handled externally, please declare throws to throw a specific exception for the convenience of the caller
    • When declaring and throwing an exception on a method, it also needs to be annotated. The purpose is to provide the caller with as much information as possible to facilitate exception handling
  • Defining exceptions with identifying messages: facilitating precise positioning of problems
  • Catch the most specific subclass exceptions first
    • If you catch an exception superclass first, such as catch (Exception e), the code that catches catch (RuntimeException E) later will not be executed
  • Do not capture Throwable classes
    • Throwable is a superclass of error and Exception. Error is a JVM and system level error. Generally, it should not be captured and processed
  • Don't fail to deal with the exception after it is caught: the root cause of the exception error cannot be located. It is recommended to at least output the log
  • Don't record and throw exceptions: it causes the same exception to output multiple same logs, so it's not easy to find the root cause of the error
  • Do not discard the original exception when packaging a new exception
    • If the original exception is discarded, the stack trace and the original exception message will be lost, which will make it difficult to analyze the exception events
  • Note: exceptions can affect performance
    • The performance cost of exception handling is very high. Creating an exception is very slow, and throwing an exception will take 1~5ms. Try not to use exceptions to control the logic of your code

5 exception and autocloseable (syntax sugar of 1.7-jdk)

  • In catching exception handling, we often open resources (TCP links, file streams) in try. In order to prevent the resource from being shut down due to exceptions, the closing of the resource needs to be executed in the finally code
  • Is there a convenient way? After the 1.7 JDK, java provides a try – with – resource syntax sugar. The resource object needs to implement autoclosable. If you open the resource in try(), the relevant resources will be closed automatically, and manual execution is no longer required, whether it is normal exit or abnormal exit
  • The subclass of InputStream inherits autoclosable, and the use example of automatically closing the resource class FileInputStream
File file = new File("./text.txt");
try (FileInputStream in =new FileInputStream(file)){
    ...//Data operation
} catch (Exception e) {
    log.error(e.getMessage(), e);
    ...
}

6 difference between throw and throws

  • Throw keyword is used inside a method. It can only be used to throw an exception. It is used to throw an exception in a method or code block. Both checked and non checked exceptions can be thrown
  • The throws keyword is used on the method declaration. It can throw multiple exceptions to identify the list of exceptions that the method may throw. A method uses throws to identify the list of exceptions that may be thrown. The method calling the method must contain the code that can handle exceptions. Otherwise, the corresponding exception must be declared with the throws keyword in the method signature

7. Learn about the Throwables class of guava

  • If you need to call chain operations on exceptions, you can use the Throwables tool class. Throwables common methods:
//Get the throwable exception chain in the form of list
public static List<Throwable> getCausalChain(Throwable throwable)
//Returns the lowest level exception
public static Throwable getRootCause(Throwable throwable)
//Converts the checked exception to a runtime exception
//Get the description output of the exception call chain (for each line)
public static String getStackTraceAsString(Throwable throwable)
//If the exception is similar to declaredType, throw an exception and pass throwable
public static <X extends Throwable> void propagateIfInstanceOf(
      @Nullable Throwable throwable, Class<X> declaredType) throws X
//throwable is passed if and only if it is a RuntimeException and Error, or an instance of X
void propagateIfPossible(Throwable, Class<X extends Throwable>) throws X
//Convert Throwable to RuntimeException. This method is not recommended
public static RuntimeException propagate(Throwable throwable)
  • example
public static void main(String args[]) throws FileNotFoundException {
    try {
        File file = new File("./text.txt");
        FileInputStream inputStream = new FileInputStream(file);
    } catch (Exception e) {
    	//Get the exception call stack information and print it (or save it in other places)
        String errorMsg = Throwables.getStackTraceAsString(e);
        System.out.println(errorMsg);
        //If e is FileNotFoundException, throw it directly
        Throwables.propagateIfInstanceOf(e, FileNotFoundException.class);
        //Other Throwable s are thrown by the RuntimeException class
        throw Throwables.propagate(e);
    }
}

Follow the official account and communicate together

Reference articles

Tags: Java Back-end Interview Exception

Posted by slindstr on Thu, 19 May 2022 10:38:24 +0300