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: