The exception of Java learning (comprehensive series)

The following is transferred from the blog garden, but some fillings (mainly the types of exceptions) and code examples are made to facilitate the understanding of the image.
This article
begins with the most basic concepts and syntax of Java exceptions, describes the basic knowledge of Java exception handling, analyzes the Java exception architecture, compares Spring's exception handling framework, and expounds the basic principles of exception handling. And the author proposes his own idea of ​​handling exceptions in a large application system, and discusses this idea by designing an exception handling framework.

1. The concept of exception and Java exception architecture

Exceptions are errors that occur during program execution. This article mainly teaches about exception handling in the Java language. The exception handling framework of the Java language is an important manifestation of the robustness of the Java language.

Java treats exceptions as objects and defines a base class java.lang.Throwable as the superclass of all exceptions. Many exception classes have been defined in the Java API, and these exception classes are divided into two categories, Error and Exception. The Java exception architecture is tree-like, and its hierarchical structure is shown in Figure 1:
write picture description here

Figure 1 Java exception architecture

The superclass of all exceptions and errors of the Thorwable class has two subclasses Error and Exception, which represent errors and exceptions respectively. The exception class Exception is divided into runtime exception (RuntimeException) and non-runtime exception, these two exceptions are very different, also known as unchecked exception (Unchecked Exception) and checked exception (Checked Exception). The differences and connections between these exceptions are described in detail below:

1. Error and Exception Error are errors that the program cannot handle, such as OutOfMemoryError, ThreadDeath, etc. When these exceptions occur, the Java Virtual Machine (JVM) typically chooses to terminate the thread. Exception is an exception that the program itself can handle. This kind of exception is divided into two categories: runtime exception and non-runtime exception. Programs should try to handle these exceptions as much as possible.

2. Runtime and non-runtime exceptions

Runtime exceptions are all exceptions of the RuntimeException class and its subclasses, such as NullPointerException, IndexOutOfBoundsException, etc. These exceptions are unchecked exceptions, which can be captured and processed in the program or not processed. These exceptions are generally caused by program logic errors, and the program should avoid the occurrence of such exceptions as much as possible from a logical point of view.

Non-runtime exceptions are exceptions other than RuntimeException, which belong to the Exception class and its subclasses. From the perspective of program syntax, it is an exception that must be handled. If it is not handled, the program cannot be compiled. Such as IOException, SQLException, etc., as well as user-defined Exception exceptions, generally do not customize checked exceptions.


Some common types of anomalies (transferred from the short book, and the source is indicated later, if you feel that there is too much content, you can skip it first):

Arithmetic exception class: ArithmeticExecption

Null pointer exception class: NullPointerException

Type casting exception: ClassCastException

Array negative subscript exception: NegativeArrayException

Array index out of bounds exception: ArrayIndexOutOfBoundsException

Security violation exception: SecurityException

End of file exception: EOFException

File not found exception: FileNotFoundException

String to Number Exception: NumberFormatException

Operation database exception: SQLException

Input and output exception: IOException

Method not found exception: NoSuchMethodException

java.lang.AbstractMethodError

Abstract method error. Thrown when the application attempts to call an abstract method.

java.lang.AssertionError

Assertion is wrong. Used to indicate an assertion failure condition.

java.lang.ClassCircularityError

Class circular dependency error. This exception is thrown when a circular dependency between classes is detected when initializing a class.

java.lang.ClassFormatError

Class is malformed. Thrown when the Java virtual machine attempts to read a Java class from a file and detects that the contents of the file do not conform to a valid format for the class.

java.lang.Error

mistake. Is the base class for all errors and is used to identify serious program execution problems. These problems usually describe some anomalous situation that should not be caught by the application.

java.lang.ExceptionInInitializerError

Initializer error. Thrown when an exception occurs during the execution of a static initializer for a class. A static initializer is a static statement segment directly contained in a class.

java.lang.IllegalAccessError

Illegal access error. This exception is thrown when an application attempts to access, modify, or call a method of a class, but violates the visibility declaration of the field or method.

java.lang.IncompatibleClassChangeError

Incompatible class change error. Thrown when an incompatible change has occurred to the class definition on which the method being executed depends on. Generally, this error is easily caused when the declaration definition of some classes in the application is modified without recompiling the entire application and running directly.

java.lang.InstantiationError

Instantiation error. Thrown when an application attempts to construct an abstract class or interface via Java's new operator.

java.lang.InternalError

internal error. Used to indicate that an internal error has occurred in the Java Virtual Machine.

java.lang.LinkageError

Link error. This error and all its subclasses indicate that a class depends on other classes, and after the class is compiled, the dependent class changes its class definition without recompiling all the classes, thereby causing an error condition.

java.lang.NoClassDefFoundError

Class definition not found error. This error is thrown when the Java virtual machine or class loader attempts to instantiate a class and cannot find a definition for the class.

java.lang.NoSuchFieldError

Domain does not exist errors. This error is thrown when an application attempts to access or modify a field of a class that does not have a definition for that field in the class definition.

java.lang.NoSuchMethodError

There is no error in the method. Thrown when an application attempts to call a method of a class that does not have a definition for that method in the class's definition.

java.lang.OutOfMemoryError

Out of memory error. Thrown when there is insufficient memory available for the Java Virtual Machine to allocate to an object.

java.lang.StackOverflowError

stack overflow error. Thrown when an application is too deep in recursive calls to overflow the stack.

java.lang.ThreadDeath

Thread ends. This error is thrown when the stop method of the Thread class is called to indicate the end of the thread.

java.lang.UnknownError

unknown mistake. Used to indicate that an unknown critical error has occurred in the Java Virtual Machine.

java.lang.UnsatisfiedLinkError

Unmet link error. Thrown when the Java virtual machine does not find a native language definition for a class declared as a native method.

java.lang.UnsupportedClassVersionError

Unsupported class version error. This error is thrown when the Java virtual machine tries to read a class file, but finds that the major and minor version numbers of the file are not supported by the current Java virtual machine.

java.lang.VerifyError

Validation error. Thrown when the validator detects an internal incompatibility or security issue in a class file.

java.lang.VirtualMachineError

Virtual machine error. Used to indicate that the virtual machine is destroyed or that the resources required to continue operations are insufficient.

java.lang.ArithmeticException

Arithmetic condition exception. For example: integer division by zero, etc.

java.lang.ArrayIndexOutOfBoundsException

Array index out of bounds exception. Thrown when the index into the array is negative or greater than or equal to the size of the array.

java.lang.ArrayStoreException

Array storage exception. Thrown when storing an object of a non-array declared type into an array.

java.lang.ClassCastException

The class shape is abnormal. Suppose there are classes A and B (A is not a parent or subclass of B), and O is an instance of A, then this exception is thrown when O is forced to be constructed as an instance of class B. This exception is often referred to as a cast exception.

java.lang.ClassNotFoundException

Class Exception not found. This exception is thrown when the application tries to construct a class based on the class name in string form and cannot find a class file with the corresponding name after traversing the CLASSPAH.

java.lang.CloneNotSupportedException

Clone exceptions are not supported. When the Cloneable interface is not implemented or the clone method is not supported, this exception is thrown when the clone() method is called.

java.lang.EnumConstantNotPresentException

There are no exceptions for enum constants. Thrown when an application attempts to access an enumeration object by name and enumeration type, but the enumeration object does not contain constants.

java.lang.Exception

root exception. Used to describe what the application wants to capture.

java.lang.IllegalAccessException

Illegal access exception. This exception is thrown when an application attempts to create an instance of a class, access properties of the class, and call methods of the class through reflection, but cannot access the definition of the class, properties, methods, or constructors at that time.

java.lang.IllegalMonitorStateException

The illegal monitoring status is abnormal. Thrown when a thread attempts to wait on a monitor for an object (O) that it does not own, or to notify other threads to wait on the monitor for that object (O).

java.lang.IllegalStateException

Illegal status exception. This exception is thrown when the method is called in the Java environment and the application is not yet in the legal calling state of the method.

java.lang.IllegalThreadStateException

Illegal thread state exception. When the county town is not in the legal calling state of a method and the method is called, an exception is thrown.

java.lang.IndexOutOfBoundsException

Index out of bounds exception. This exception is thrown when the index value of accessing a sequence is less than 0 or greater than or equal to the size of the sequence.

java.lang.InstantiationException

instantiation exception. This exception is thrown when trying to create an instance of a class that is an abstract class or interface through the newInstance() method.

java.lang.InterruptedException

Aborted exception. This exception is thrown when a thread is in a long-time waiting, sleeping or other suspended state, and other threads terminate the thread through the interrupt method of Thread.

java.lang.NegativeArraySizeException

Array size is negative exception. Thrown when creating an array with a negative size value.

java.lang.NoSuchFieldException

Property does not exist exception. Thrown when accessing a nonexistent property of a class.

java.lang.NoSuchMethodException

There is no exception to the method. Thrown when a non-existent method of a class is accessed.

java.lang.NullPointerException

Null pointer exception. Thrown when an application attempts to use null where an object is required. For example: calling the instance method of the null object, accessing the properties of the null object, calculating the length of the null object, using the throw statement to throw null and so on.

java.lang.NumberFormatException

Number format is abnormal. This exception is thrown when an attempt is made to convert a String to the specified numeric type, and the string does not meet the required format of the numeric type.

java.lang.RuntimeException

Runtime exception. Is the parent class for all exceptions that can be thrown during normal operation of the Java virtual machine.

java.lang.SecurityException

Security exception. Exception thrown by the security manager to indicate a security violation.

java.lang.StringIndexOutOfBoundsException

String index out of bounds exception. Thrown when accessing a character in a string using an index value that is less than 0 or greater than or equal to the sequence size.

java.lang.TypeNotPresentException

Type does not exist exception. This exception is thrown when an application attempts to access a type by its string representation of a type name, but cannot find the type with the given name. The difference between this exception and ClassNotFoundException is that the exception is an unchecked (not checked) exception, while ClassNotFoundException is a checked (checked) exception.

java.lang.UnsupportedOperationException

Unsupported method exception. An exception indicating that the requested method is not supported.

Author: Xiaoshaying 168
Link: https://www.jianshu.com/p/60acb51b71a4
Source: Jianshu The
copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.


2. Exception capture and handling

The capture and handling of Java exceptions is not easy to grasp. If handled improperly, it will not only greatly reduce the readability of the program code, but also lead to low system performance, and even cause some hard-to-find errors.

Java exception handling involves five keywords, namely: try, catch, finally, throw, throws. The following will be introduced step by step, by understanding these five keywords, master the basic knowledge of exception handling.

1. The basic syntax of exception handling In java, the complete syntax of exception handling is: try{ //(trying to run) program code}catch(variable name of exception type exception){ //exception handling code}finally{ // An exception occurs, the code that is always executed before the method returns }

The above syntax has three code blocks: try block, which means to try to run the code, the code in the try block is subject to exception monitoring, and when an exception occurs in the code, an exception object will be thrown.

The catch statement block captures the exception that occurs in the try code block and handles the exception in its code block. The catch statement takes a parameter of type Throwable, indicating the type of exception that can be caught. When an exception occurs in try, catch will catch the exception and match its own exception type. If it matches, execute the code in the catch block, and point the catch block parameter to the thrown exception object. There can be more than one catch statement, which is used to match one of the multiple exceptions. Once it is matched, it will not try to match other catch blocks. Through the exception object, you can obtain the complete JVM stack information when the exception occurs, as well as the exception information and the cause of the exception.

The finally block is the block immediately following the catch statement. This block is always executed before the method returns, regardless of whether the try block has an exception or not. And this block of statements is always executed before the method returns. The purpose is to give the program a chance to remedy. Doing so also reflects the robustness of the Java language. 2. Problems that should be paid attention to in the three statement blocks of try, catch and finally. First, the three statement blocks of try, catch and finally cannot be used alone. The three can be composed of try...catch...finally, try...catch, try...finally In this structure, there can be one or more catch statements, and at most one finally statement. Second, the scope of the variables in the three code blocks of try, catch, and finally is inside the code block, and they are independent and cannot access each other. If you want to be accessible in all three blocks, you need to define the variable outside of those blocks. Third, when there are multiple catch blocks, only one of the exception classes will be matched and the catch block code will be executed, and no other catch blocks will be executed, and the order of matching catch statements is from top to bottom.

class MyException extends Exception{            //创建自己的异常类,继承与Exception
    String message;
    public MyException(String ErrorMessage){        //编写构造方法,对message进行赋值
        message=ErrorMessage;
    }
    public String getMessage(){         //对getMessage()方法进行重写
        return message;
    }
}
public class Demo {
    public static int quotient(int x,int y)throws MyException{ //throws申明可能抛出的异常类型
        if(y<0){
            throw new MyException("除数不能为负数");   //throw抛出异常检查 
        }
        return x/y;
    }
    public static void main(String[] args) {
        try{        
            int result=quotient(1,0);
        }catch(MyException e){              //一个try可以搭配多个异常
            System.out.println(e.getMessage());
        }catch(ArithmeticException e){
            System.out.println("除数不能为0");
        }catch(Exception e){
            System.out.println("程序发生了其他异常");
        }finally{
            System.out.println("进行finally调用");
        }
    }
}

Program output:

除数不能为0
进行finally调用

Here is an explanation:
if the exception that occurs is Errir, RuntimeException or their subclasses, you can declare the exception to be thrown without using the throws keyword, and the compiler can still pass it smoothly, but it will be thrown by the system at runtime. Such as ArithmeticException is the case.
3. Throw, throws keyword The throw keyword is used inside the method body to throw a Throwable type exception. If a checked exception is thrown, the type of exception the method may throw should also be declared in the method header. The caller of this method must also check to handle the thrown exception. If all methods throw the acquired exception layer by layer, the JVM will process it eventually, and the processing is also very simple, that is, printing the exception message and stack information. If an Error or RuntimeException is thrown, the caller of this method can choose to handle the exception. The translation of exceptions is explained below. The throws keyword is used in the method declaration part outside the method body to declare that the method may throw certain exceptions. Only if a checked exception is thrown, the caller of this method must handle or rethrow the exception. When the caller of the method is unable to handle the exception, it should continue to throw, instead of swallowing it and printing the stack information in the catch block to deal with it reluctantly. 3. The common method getCause() in the Throwable class: returns the reason for throwing the exception. Returns null if the cause does not exist or is unknown. getMessage(): Returns the abnormal message information. printStackTrace(): The stack trace of the object is output to the error output stream as the value of the field System.err.

3. General principles of exception handling

1. If it can be dealt with, deal with it as soon as possible. If it can't be dealt with, it will be digested or converted to RuntimeException. Because it is problematic for an application system to throw a large number of exceptions, the possibility of exceptions should be controlled as much as possible from the perspective of program development. 2. For checked exceptions, if they cannot be handled effectively, it is better to convert them to RuntimeException and throw them. This also allows the upper-level code to have a choice - it can be processed or not. 3. For an application system, it should have its own set of exception handling framework, so that when an exception occurs, a unified processing style can be obtained, and elegant exception information can be fed back to the user.

4. Exception translation and exception chain 1. The principle of exception translation

The so-called exception translation is to convert one kind of exception into another new exception, perhaps this new exception can more accurately express the abnormality of the program.

In Java, there is a concept of exception cause. The exception cause causes the exception object that currently throws the exception. Almost all exception construction methods with exception causes use Throwable type as parameters, which also provides direct support for exception translation. , because exceptions and errors of any kind are subclasses of Throwable. For example, to convert SQLException to another new exception DAOException, you can write:

First customize an exception DAOException:

public class DAOException extends RuntimeException { //(Some code is omitted) public DAOException(String message, Throwable cause) { super(message, cause); } } For example, if there is an exception object e of type SQLException, to convert it to DAOException, you can do this Write:

DAOException daoEx = new DAOException ( “SQL异常”, e);

Exception translation is for all classes that inherit the Throwable superclass. From the perspective of programming syntax, subclasses can be converted to each other. However, from the perspective of rationality and system design, exceptions can be divided into three categories: Error, Exception, and RuntimeException. The author believes that a reasonable translation diagram should be shown in Figure 2:

Figure 2 Exception translation

Why do you do that? The author believes that there is a set of philosophical ideas in the handling of exceptions: for an application system, any exception or error that occurs in the system is a system "runtime" exception to the operating user, and is an exception within the application system. . This is also the guiding principle of exception translation and application system exception framework design. There are many negative effects of handling unchecked exceptions in a large number of systems, the most important aspect is that the code is less readable, the program is complicated to write, and the code for exception handling is also very weak. Therefore, it is necessary to convert these checked exceptions Exception and error Errors into RuntimeException exceptions, and let the programmer decide whether to catch and handle the exceptions that occur according to the situation.

The three lines in the figure identify the direction of conversion, and there are three cases:

①: Error to Exception: Convert the error to an exception and continue to throw. For example, in the Spring WEB framework, the doDispatch() method of org.springframework.web.servlet.DispatcherServlet translates the captured error into a NestedServletException. The purpose of this is to maximize the recovery of the negative impact caused by the error. Because an Error is often a serious error, it may cause the system to hang.

②: Exception to RuntimeException: Converting checked exceptions to RuntimeException can make the program code more elegant, allowing developers to focus on the manager to design more reasonable program code, which in turn increases the possibility of system exceptions.

③: Error to RuntimeException: The purpose is still the same. Translate all exceptions and errors into unchecked exceptions, which makes the code more concise and facilitates unified handling of error and exception information.

1. Exception chain

The exception chain, as the name suggests, is to pass the cause of the exception one by one, that is, pass the underlying exception information to the upper layer, so that it is thrown layer by layer. A simple model is given in the Java API documentation:

try { lowLevelOp(); } catch (LowLevelException le) { throw (HighLevelException) new HighLevelException().initCause(le); }

When the program catches a low-level exception le, the processing section chooses to continue throwing a new higher-level exception to the caller of this method. In this way, the cause of the exception is passed layer by layer. In this way, the exception at the top level recursively calls the getCause() method to traverse the cause of the exception at each level. This is how Java exception chains work. There are few practical applications of the exception chain. When an exception occurs, it is not a good idea to throw it up layer by layer. What can the upper layer do when they get these exceptions? And throwing exceptions layer by layer will consume a lot of resources, because a complete exception chain information needs to be saved.

5. Design an efficient and reasonable exception handling framework

For an application system, all exceptions that occur are viewed by the user as internal exceptions of the application system. Therefore, an exception framework of the application system should be designed to handle all exceptions during the operation of the system.

Based on this point of view, an application exception can be designed such as called AppException. And for the user, these exceptions all occur when the application system is running, so AppException should inherit RuntimeException, so that all other exceptions in the system are translated into AppException, when the exception occurs, the front end receives AppExcetpion and makes a unified deal with. Draw the exception handling framework as shown in Figure 3:

Figure 3 Exception handling framework of an application system

In this design diagram, AppRuntimeException is the base class of system exceptions. This exception is only thrown externally. This exception can be received and processed by the front-end (client). When an exception occurs, the relevant components of the client will capture and process these exceptions. friendly” message to customers. In the lower layer of AppRuntimeException, there are various exceptions and errors, which are eventually translated into AppRuntimeException. Some other subclass exceptions can be designed under AppRuntimeException, such as AppDAOException, OtherException, etc., which are handled flexibly according to actual needs. The next step is how to convert the captured primitive exceptions such as SQLException and HibernateException into a more advanced AppDAOException.

In terms of exception framework design, it is generally accepted that Spring is better. All exceptions in Spring can be represented by org.springframework.core.NestedRuntimeException, and the base class inherits RuntimeException. The Spring framework is very large, so many subclasses of NestedRuntimeException and tools for exception conversion have been designed, which are all excellent design ideas.

Six, Java exception handling summary

Review the full text and summarize the main points of Java exception handling:

1. Exceptions are errors that occur during the running process of a program. In Java, classes are used to describe them, and objects are used to represent specific exceptions. Java distinguishes it as Error and Exception, Error is the error that the program cannot handle, Exception is the error that the program can handle. Exception handling is for program robustness. 2. Java exception classes come from Java API definitions and user extensions. Exception translation can be achieved by inheriting the Java API exception class. 3. Exceptions are handled if they can be handled, thrown if they cannot be handled, and JVM will handle the unhandled exceptions. 4. Exceptions can be propagated and translated to each other, but a reasonable exception translation direction should be selected according to needs. 5. For an application system, it is very important to design a good exception handling system. This should be taken into account when designing the system.

Guess you like

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