Programming language JavaSE (Fundamentals) -- exception mechanism
Daily saying: the water drop penetrating the stone, its strength comes from accumulation over time
preface:
Referenced crazy Java basic video—— Crazy Java basic video
catalogue
Differences and connections between exceptions
3. Check abnormal and unchecked abnormal
Order of execution of try catch finally return
Abnormal body System structure
Java treats exceptions as objects and defines a base class java.lang.Throwable As a superclass for all exceptions.
Many Exception classes have been defined in the Java API. These Exception classes are divided into two categories: Error and Exception.
Java exception hierarchy diagram:
As can be seen from the figure, all exception types are built-in classes Throwable Subclass of, so Throwable At the top of the exception class hierarchy.
Next, Throwable It is divided into two different branches. One branch is Error, which indicates that you do not want to be captured by the program or the program Unhandled Error. The other branch is Exception, which represents the Exception that the user program may catch or the Exception that the program can handle.
Exception class Exception It is also divided into runtime exceptions( RuntimeException )And non runtime exceptions. Java exceptions can be divided into unchecked exceptions( Unchecked Exception )And check for abnormalities( Checked Exception ).
Differences and connections between exceptions
1.Error
error class object by Java The virtual machine generates and throws most errors regardless of what the coder is doing.
For example:
Java virtual machine running error( Virtual MachineError ), Occurs when the JVM no longer has the memory resources needed to continue the operation OutOfMemoryError . When these exceptions occur, the Java virtual machine (JVM) will generally choose thread termination;
There is also a class definition error that occurs when the virtual machine attempts to execute an application( NoClassDefFoundError ), Link error( LinkageError ). These errors are not traceable because they are outside the control and processing power of the application, and most of them are not allowed when the program is running.
For a well-designed application, even if an error does occur, it should not try to deal with the exception caused by it. In Java, errors are usually used Error Subclass description of.
2.Exception
In Exception There is an important subclass in the branch RuntimeException (runtime Exception), this type of Exception is automatically defined for the program you write ArrayIndexOutOfBoundsException (array subscript out of bounds) NullPointerException (null pointer Exception), ArithmeticException (arithmetic Exception) MissingResourceException (missing resources) ClassNotFoundException (class not found) and other exceptions. These exceptions are not checked. The program can choose to capture and handle them or not.
These exceptions are generally caused by program logic errors, and the program should avoid such exceptions as much as possible from a logical point of view RuntimeException Exceptions other than are collectively referred to as non runtime exceptions, which belong to Exception Class and its subclasses are exceptions that must be handled from the perspective of program syntax. If they are not handled, the program cannot be compiled, such as IOException , SQLException And user-defined Exception Exceptions. Generally, exceptions are not checked by user.
Note: error and Exception Differences between: Error It is usually a catastrophic fatal error that cannot be controlled and handled by the program. When these exceptions occur, the Java virtual machine (JVM) will generally choose to terminate the thread; Exception Usually, it can be handled by the program, and these exceptions should be handled as much as possible in the program.
3. Check abnormal and unchecked abnormal
Check exception: it is a reasonable and tolerable exception that is easy to occur during the correct program operation. To a certain extent, the occurrence of this exception is predictable, and once this exception occurs, it must be handled in some way.
Resolution: except RuntimeException and its subclasses, other Exception classes and their subclasses belong to check exceptions. When such exceptions may occur in the program, either use the try catch statement to catch them or throw them with the throw clause, otherwise the compilation cannot pass.
Do not accept check exceptions: including RuntimeException and its subclasses and Error.
Analysis: unchecked exception Is an exception that the compiler does not require forced handling, Check for abnormalities Is an exception that the compiler requires to be handled.
Java exception handling
1.try-catch
try{ //code that might generate exceptions }catch(Exception e){ //the code of handling exception1 }catch(Exception e){ //the code of handling exception2 }
To understand exception capture, you also need to understand Monitoring area It is a piece of code that may generate exceptions, followed by the code that handles these exceptions.
Therefore, it can be seen that the above try-catch What is described is the monitoring area, key words try The next pair of braces wrap a piece of code that may have exceptions, which is the monitoring area. If an exception occurs during the running of a Java method, an exception object is created.
Throw the exception out of the monitoring area, and the Java runtime system is responsible for finding the matching exception catch Clause to catch an exception. If there is one catch If the statement matches, execute the catch The exception handling code in the block does not try to match anything else catch Block.
Matching principle: if the exception object thrown belongs to catch Clause, or a subclass belonging to the exception class, the generated exception object is considered to be the same as catch The block matches the exception type caught.
public class TestException { public static void main(String[] args) { int a = 1; int b = 0; try { // try monitoring area if (b == 0) throw new ArithmeticException(); // Throw an exception through the throw statement System.out.println("a/b The values are:" + a / b); System.out.println("this will not be printed!"); }catch (ArithmeticException e) { // Catch catch exception System.out.println("Program exception, variable b Cannot be 0!"); } System.out.println("The program ends normally."); } } //output Program exception, variable b Cannot be 0! The program ends normally.
Note: an exception description is displayed, Throwable Overloaded toString() Method (by Object Definition), so it will return a string containing the exception description. For example, the previous catch Block rewritten as:
catch (ArithmeticException e) { // Catch catch exception System.out.println("The program has an exception"+e); } //An exception java.lang.ArithmeticException occurred in the output program The program ends normally.
The arithmetic exception belongs to the runtime exception, so in fact, the exception does not need to be thrown by the program, and the system will throw it automatically at runtime. If the try catch program is not used, it will not be executed.
public class TestException { public static void main(String[] args) { int a = 1; int b = 0; System.out.println("a/b The values are:" + a / b); System.out.println("this will not be printed!"); } } result: Exception in thread "main" java.lang.ArithmeticException: / by zero at TestException.main(TestException.java:7)
Use multiple catch statements: in many cases, multiple exceptions may be caused by a single code segment. To deal with this situation, we need to define two or more catch Clause, each clause catches one type of exception. When the exception is thrown, each catch Clauses are checked in turn, and the first clause matching the exception type is executed when a catch After the clause is executed, other clauses will be bypassed.
Precautions for writing multiple catch statement blocks:
Order problem: small first and then large, that is, subclasses first and then parent classes
be careful:
Java describes exception types through exception classes. For multiple catch Clause, you should try to capture the underlying exception class catch Clause first, and try to catch the exception class at a relatively high level catch Clause after. Otherwise, the of the underlying exception class is caught catch Clause may be masked.
Nested try statements: try Statements can be nested. That is, one try Statement can be in another try Inside the block. Every entry try Statement, the context of the exception will be pushed onto the stack. If an internal try Catch statement without special exception Handler, the stack will pop up, next try Declarative catch The handler checks to see if it matches. This process will continue until a catch Statements are matched successfully, or until all nested try The statement has been checked. without catch Statement, the Java runtime system will handle this exception.
class NestTry{ public static void main(String[] args){ try{ int a = args.length; int b = 42 / a; System.out.println("a = "+ a); try{if(a == 1){ a = a/(a-a); } if(a == 2){ int c[] = {1}; c[42] =99; } }catch(ArrayIndexOutOfBoundsException e){ System.out.println("ArrayIndexOutOfBounds :"+e); } }catch(ArithmeticException e){ System.out.println("Divide by 0"+ e); } } } //Analysis run: D:\java>java NestTry one a = 1 Divide by 0java.lang.ArithmeticException: / by zero D:\java>java NestTry one two a = 2 ArrayIndexOutOfBounds :java.lang.ArrayIndexOutOfBoundsException: 42
Analysis: as shown in the program, the program nested another in one try block try Block. The program works as follows: when you execute the program without command line parameters, the external try The block will generate an exception divided by 0.
The program is executed with a command-line parameter, which is nested try Block generates an exception divided by 0 due to internal catch If the block does not match this exception, it will pass the exception to the external try Block, in which external exceptions are handled. If you execute the program with two command line parameters, it will be executed by the internal try Block generates an array boundary exception.
Note: when there is a method call, try Nesting of statements can occur covertly. For example, we can place calls to methods in a try Block. Inside the method, there is another try sentence.
In this case, the method is internal try The method is still nested outside try In the block. Next, we will modify the above example to nested try Move the block to the inside of the method nesttry(): the result is still the same!
class NestTry{ static void nesttry(int a){ try{if(a == 1){ a = a/(a-a); } if(a == 2){ int c[] = {1}; c[42] =99; } }catch(ArrayIndexOutOfBoundsException e){ System.out.println("ArrayIndexOutOfBounds :"+e); } } public static void main(String[] args){ try{ int a = args.length; int b = 42 / a; System.out.println("a = "+ a); nesttry(a); }catch(ArithmeticException e){ System.out.println("Divide by 0"+ e); } } }
2.throw
So far, we have only obtained exceptions thrown by the Java runtime system. However, we can also use throw Statement throws an explicit exception.
Grammatical form:
throw ThrowableInstance;
ThrowableInstance here must be Throwable Class type or Throwable An object of subclass type. Simple data types, such as int , char , And non Throwable Class, for example String or Object , Cannot be used as an exception.
There are two ways to get Throwable Objects: in catch Use arguments in clauses or new Operator creation. Program execution completed throw Stop immediately after the statement; throw Any subsequent statements are not executed, the nearest try Block is used to check whether it contains an exception that matches the exception type catch sentence.
If a matching block is found, control turns to the statement; If it's not found, it's surrounded by two times try Block, and so on. If no match is found catch Block, the default exception handler interrupts the execution of the program and prints the stack trace.
class TestThrow{ static void proc(){ try{ throw new NullPointerException("demo"); }catch(NullPointerException e){ System.out.println("Caught inside proc"); throw e; } } public static void main(String [] args){ try{proc(); }catch(NullPointerException e){ System.out.println("Recaught: "+e); } } }
The program handles the same error twice. First, main() The method sets up an exception relation and then calls proc(). The proc() method sets up another exception handling relationship and immediately throws an exception NullPointerException Instance, NullPointerException stay main() Captured again in.
This program describes how to create a Java standard exception object, paying special attention to this line:
throw new NullPointerException("demo");
Analysis: here new Used to construct a NullPointerException Instance, all Java built-in runtime exceptions have two
Two construction methods: one without parameters and one with a string parameter.
When the second form is used, the parameter specifies a string describing the exception. If the object is used as print() perhaps println() The string is displayed. This can also be achieved by calling getMessage(), which is generated by Throwable Defined.
3.throws
If a method can cause an exception but does not handle it, it must specify this behavior so that method callers can protect themselves from exceptions. To do this, we can include a throws Clause.
A throws Clause lists all exception types that may be thrown by a method. It's important for Error Or RuntimeException And all exceptions of types other than their subclasses are necessary. All other types of exceptions that a method can throw must be throws Clause, otherwise a compilation error will result.
public void info() throws Exception { //body of method }
Exception is all the exceptions that may be thrown by the method, or it can be an exception list, separated by commas.
[example]
class TestThrows{ static void throw1(){ System.out.println("Inside throw1 . "); throw new IllegalAccessException("demo"); } public static void main(String[] args){ throw1(); } }
There are two errors in this example. First, the throw1() method does not want to handle the resulting exception, so it must declare throws Clause to enumerate possible exceptions, i.e IllegalAccessException ; secondly, main() Method must define try/catch Statement to catch the exception.
The correct examples are as follows:
class TestThrows{ static void throw1() throws IllegalAccessException { System.out.println("Inside throw1 . "); throw new IllegalAccessException("demo"); } public static void main(String[] args){ try { throw1(); }catch(IllegalAccessException e ){ System.out.println("Caught " + e); } } }
Throw exception rule
1. If it is an unchecked exception( unchecked exception ), Namely Error , RuntimeException Or their subclasses, you can not use throws Keyword to declare the exception to be thrown. The compilation can still pass smoothly, but it will be thrown by the system at run time.
2. You must declare any check exceptions that the method can throw( checked exception ). That is, if a method may have a checked exception, either use try-catch Statement capture, or throws Clause declaration throws it, otherwise it will cause compilation errors.
3. Only when an exception is thrown, the caller of the method must handle or re throw the exception. When the caller of the method is unable to handle the exception, he should continue to throw it instead of swallowing it.
4. The calling method must follow the handling and declaration rules of any searchable exception. If you override a method, you cannot declare an exception different from the override method. Any exception declared must be the same or subclass of the exception declared by the overridden method.
4.finally
When an exception occurs, the execution of the method will usually make a steep nonlinear turn, which will even lead to the return of the method prematurely. For example, if a method opens a file, closes it, and then exits, you don't want the code that closes the file to be bypassed by the exception handling mechanism. finally Keyword is designed to handle such accidents.
finally, the code block created in try/catch After the block is completed, another try/catch Execute before.
Finally, the block will execute whether there is an exception thrown or not. If an exception is thrown, even if there is no catch Clause match, finally It will also be implemented.
A method will start from a try/catch Any time a block returns to the calling program, it passes through an uncapped exception or an explicit return statement, finally Clause will be executed until the method returns. This is useful in closing file handles and freeing any other resources allocated at the beginning of the method.
Note: finally Clauses are optional, with or without, but each try Statement requires at least one catch perhaps finally Clause.
[example]
class TestFinally{ static void proc1(){ try{System.out.println("inside proc1"); throw new RuntimeException("demo"); }finally{ System.out.println("proc1's finally"); } } static void proc2(){ try{System.out.println("inside proc2"); return ; } finally{ System.out.println("proc2's finally"); } } static void proc3(){ try{ System.out.println("inside proc3"); }finally{ System.out.println("proc3's finally"); } } public static void main(String [] args){ try{ proc1(); }catch(Exception e){ System.out.println("Exception caught"); } proc2(); proc3(); } }
[results]
Note: if finally Block and one try Combined use, finally Block will be in try Execute before end.
Order of execution of try catch finally return
1. Execute try, catch , Assign a value to the return value
2. Execute finally
3.return
Custom exception
Using Java's built-in exception class can describe most exceptions during programming. In addition, users can customize exceptions. User defined exception class, just inherit Exception Class.
Using custom exception classes in programs can be roughly divided into the following steps:
1. Create a custom exception class.
2. Adopted in the method throw Keyword throws an exception object.
3. If an exception is handled in the method that currently throws an exception, you can use try-catch Statement capture and processing; Otherwise, it is passed at the declaration of the method throws Keyword indicates the exception to be thrown to the method caller to continue with the next operation.
4. Catch and handle exceptions in the caller of the exception method.
[example]
class MyException extends Exception { private int detail; MyException(int a){ detail = a; } public String toString(){ return "MyException ["+ detail + "]"; } } class TestMyException{ static void compute(int a) throws MyException{ System.out.println("Called compute(" + a + ")"); if(a > 10){ throw new MyException(a); } System.out.println("Normal exit!"); } public static void main(String [] args){ try{ compute(1); compute(20); } catch(MyException me){ System.out.println("Caught " + me); } } }