Java exception mechanism

1. Exception overview

The Throwable class is the superclass for all errors or exceptions in the Java language. Thrown by the Java Virtual Machine or by the Java throw statement only if the object is an instance of this class (or one of its subclasses). Similarly, only this class or one of its subclasses can be a parameter type in a catch clause.

Instances of two subclasses, Error and Exception , are typically used to indicate that an exceptional condition has occurred.

1.1 Anomaly classification:

Exceptions include Exception and Error, and their characteristics are as follows:

  • Exception

    • 1. Can be checked or unchecked.
    • 2. Indicates an error caused by program code.
    • 3. Should be handled at the application level.
    • 4. Divided into compile-time exceptions (which must be handled) and runtime exceptions
  • Error

    • 1. Always unchecked.
    • 2. Often used to indicate system errors or errors in underlying resources.
    • 3. If possible, it should be captured at the system level.

Checked exceptions and unchecked exceptions :
Unchecked exceptions refer to the java.lang.RuntimeException and java.lang.Error classes and their subclasses, and all other exception classes are called Checked exception (checked exception). The only difference between the two is that when a checked exception is used, its legality is checked by the compiler at compile time.

1.2 Inheritance system

The thick lines in the figure below show the abnormal system:
Java exception inheritance system


2. The default processing scheme of the JVM

  • 1. Output information such as the name of the exception, the cause of the error and the location of the exception to the console

  • 2. The program stops executing


3. Compile-time exceptions and runtime exceptions

Exceptions in Java are divided into two categories: compile-time exceptions and runtime exceptions . Under the Exception inheritance system, all instances of the RuntimeException class and its subclasses are called runtime exceptions, and other exceptions are compile-time exceptions

  • 1. An exception
    Java program must be displayed and handled during compilation, otherwise the program will have an error and cannot be compiled

  • 2. Runtime exceptions
    do not have to be handled explicitly, and can be handled like compile-time exceptions


4. Exception handling

4.1 Treatment plan

1. try...catch...finally (finally is not required)

Attention to detail

  • 1. The statement after the exception occurs in the try block is no longer executed. Once a matching exception type is found, go to the corresponding catch block to execute the relevant logic, and then try...catch is over.

  • 2. The catch block can capture a variety of exceptions, but the scope must be captured from small to large. The exception can be as clear as possible, and try not to use a large range to handle it.

  • 3. In non-special cases, finally will be executed, so you can do some resource recovery work in this method

示例1try {
            try块,正常执行的代码
        } catch (Exception e) {
            catch块,进行一场捕获,可以有多个catch
        } finally {
            finally块,通常一定会执行,一般用于释放资源
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. throws (used on method declarations)

示例2:
        public void getBitmapFromUrl() throws IOException{

        }
  • 1
  • 2
  • 3
  • 4
  • 5

If an exception is thrown, the caller must handle or throw the exception

4.2 finally

4.21. Features of finally

  • The body of the statement controlled by finally will be executed
  • Special case: jvm exits before execution to finally (such as System.exit(0)).

Note: If the JVM exits before finally executing, there is no guarantee that the finally block will execute.

4.22. The role of finally

  • Used to release resources, which will be seen in IO stream operations and database operations

4.23. The difference between final, finally and finalize

final : final meaning, can modify classes, member variables, member methods

  • 1. Modified classes, classes cannot be inherited
  • 2. Modified variables, variables become constants
  • 3. Modified methods, methods cannot be overridden

finalize : is a method of the Object class, used for garbage collection
finally : is a part of exception handling, used to release resources.

一般来说,代码肯定会执行。特殊情况:在执行到finally之前jvm退出了
  • 1
  • 2

Thinking: If there is a return statement in the catch, will the finally code still be executed? If so, is it before the return or after the return?
will execute. and before.


5. Methods in Throwable

5.1. Method summary

 Throwable getCause() 
          返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null。 
 String getMessage() 
          返回此 throwable 的详细消息字符串。 

 String getLocalizedMessage() 
            创建此 throwable 的本地化描述。 子类可以重写此方法,以便生成特定于语言环境的消息。
            对于不重写此方法的子类,默认实现返回与 getMessage() 相同的结果。 
 StackTraceElement[] getStackTrace() 
          提供编程访问由 printStackTrace() 输出的堆栈跟踪信息。 
 void printStackTrace() 
          将此 throwable 及其追踪输出至标准错误流。 
 void printStackTrace(PrintStream s) 
          将此 throwable 及其追踪输出到指定的输出流。 
 void printStackTrace(PrintWriter s) 
          将此 throwable 及其追踪输出到指定的 PrintWriter。 
 String toString() 
          返回此 throwable 的简短描述。结果是以下字符串的串联:  
          1.此对象的类的 name 
          2.": "((冒号和一个空格) 
          3、调用此对象 getLocalizedMessage方法(默认与getMessage()返回相同的结果)的结果
        如果 getLocalizedMessage 返回 null,则只返回类名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5.2. Example of use

public class ExceptionDemo {
    public static void main(String[] args) {
        DateFormat formatter=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            String date = formatter.format(new Date("2016-1-1"));
            System.out.println(date);
        } catch (Exception e) {
            e.printStackTrace();
            //System.out.println(e.toString());
            //System.out.println(e.getMessage());
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

6. Distinguish throws and throws

6.1 throws

When defining a functional method, it is necessary to expose the problems that arise for the caller to deal with. Then it is identified on the method by throws. Features are as follows:

  • 1. Used after the method name of the method declaration, followed by the exception class name
  • 2. You can declare that multiple exceptions are thrown, followed by multiple exception class names, separated by commas
  • 3. Indicates that an exception is thrown, which is handled by the caller of the method
  • 4.throws indicates a possibility of exceptions, and these exceptions do not necessarily occur

6.2 throw

There is a certain situation inside the function method, the program cannot continue to run, and when a jump is required, the exception object is thrown by throw. Features are as follows:

  • 1. Used in the method body, it means throwing an exception object, and only one exception object can be thrown at a time
  • 2. If throw can be executed, some kind of exception must be thrown, and the code after the throw statement is no longer executed.

6.3 Handling

  • For compile-time exceptions, the caller must handle it.
  • For runtime exceptions, the caller does not need to handle them.

6.4 Abnormal Precautions

  • When a subclass overrides a superclass method, the subclass method must throw the same exception or a subclass of the superclass exception.
  • If the method of the parent class throws multiple exceptions, when the child class overrides the method of the parent class, it can only throw the same exception or its subset, and the child class cannot throw exceptions that the parent class does not have.
  • If the overridden method does not throw an exception, the subclass method must not throw an exception. If an exception occurs in the subclass method, the subclass can only try, not throws

Note: The exceptions mentioned here are all checked exceptions


7. Custom exception class

Custom exception class: To inherit from an exception class. Exceptions inherited from Exception are compile-time exceptions, and exceptions inherited from RuntimeException are runtime exceptions.
The following example:

class CustomException extends Exception{

private static final long serialVersionUID = -2008123398676394901L;

    public CustomException(String msg) {
            super(msg);
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

8. New features of JDK7 for exception handling

8.1 Handling Multiple Exceptions

In jdk7, multiple exceptions can be handled simultaneously at one exception level in the following form:

try{

}catch(异常名1 | 异常名2 | ...  变量 ) {
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Example

try {
         // to do
 } catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
         // deal with exception
 }
  • 1
  • 2
  • 3
  • 4
  • 5

Precautions:

  • 1. The processing method is to give the same processing for the same type of problems.

  • 2. Multiple exceptions must be in a level relationship.

8.2 addSuppressed

For versions before jdk, if an exception occurs in the try block and the logic of the finally method is also abnormal, the previous part of the exception information will be lost. That is, when the finally method exception is thrown, the previous exception will be suppressed because of the exception, so that it cannot be thrown normally, resulting in the loss of some exception information. jdk7 provides the addSuppressed method to record these suppressed exception information. Suppressed exceptions will appear in the stack information of the thrown exception, and these exceptions can also be obtained through the getSuppressed method. Using the addSuppressed method allows us to get complete exception stack information to facilitate development and debugging.

The following example:

 /**
     * @param input
     * @param def
     * @throws Exception
     */
    public static void useAddSuppressed(int input, String def) throws Exception {
        java.lang.Exception exception = null;
        int result = 0;
        try {
            result = 2 / input;
        } catch (ArithmeticException e) {
            exception = e;
            throw e;
        } finally {
            if (result == 0) {
                try {
                    result = Integer.parseInt(def);
                } catch (NumberFormatException e) {
                    if (exception != null) {
                        exception.addSuppressed(e); // 将信息添加到异常的堆栈信息
                    } else {
                        exception = e;
                    }
                }

                if (exception != null)
                    throw exception;
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

When calling the method as follows:

try {
        useAddSuppressed(0, "hello");
    } catch (Exception e) {
        e.printStackTrace();
    }
  • 1
  • 2
  • 3
  • 4
  • 5

The output exception information is as follows, and it can be seen that the complete exception information is output:

java.lang.ArithmeticException: / by zero
    at com.yu.kotlin.oop.ArrayTest.useAddSuppressed(ArrayTest.java:50)
    at com.yu.kotlin.oop.ArrayTest.main(ArrayTest.java:31)
    Suppressed: java.lang.NumberFormatException: For input string: "hello"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.lang.Integer.parseInt(Integer.java:580)
        at java.lang.Integer.parseInt(Integer.java:615)
        at com.yu.kotlin.oop.ArrayTest.useAddSuppressed(ArrayTest.java:57)
        ... 1 more
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

8.3 The try-with-resources statement

Java 7 introduces a new usage of try statement for resource management, simplifying the structure of try...catch...finally, while ensuring that the used resources can be released. The following code example:

public static String readFile(String path) throws IOException {
     try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
         StringBuilder sb = new StringBuilder();
         String line = null;
         while ((line = reader.readLine()) != null) {
             sb.append(line);   // 添加内容
             sb.append(String.format("%n")); // 换行
         }
         return sb.toString();
     }
 // 不需要finally块来进行手动回收
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

The application of resources is carried out in the try clause, and the release of resources is done automatically.

Use the try-with-resources statement to throw exceptions:

  • Exceptions may occur in try statements, throw try block related exceptions
  • It may occur when releasing resources, throwing exceptions related to resource release
  • The above two occur at the same time, throw the exception related to the try block, and add the exception that occurs when the resource is released as a suppressed exception, that is, through the Throwable.addSuppressed method. Get all exception information.

Note :
The resource Java class that can be managed by the try statement needs to meet a condition. It must implement the java.lang.AutoCloseable interface, otherwise a compilation error will occur. When the resource needs to be released, the close method implemented by its interface will be called automatically.

try-with-resources can also manage multiple resources. When managing multiple resources, exceptions may occur when each resource is released. All of these exceptions are added to the list of suppressed exceptions for resource initialization exceptions or exceptions thrown in try blocks.

/**
  * 复制文件
  * @param src 源
  * @param dest 目的
  * @throws IOException
  */
 public static void copyFile(String src, String dest) throws IOException {
     try (BufferedInputStream input = new BufferedInputStream(new FileInputStream(src));
          BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(dest))) {
         byte[] buffer = new byte[1024 * 4];
         int length = -1;
         while ((length = input.read(buffer)) != -1) { // read
             output.write(buffer, 0, length);  // write
         }
     }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

The catch and finally statements can also be used in the try-with-resource statement, in which the catch clause can catch various exceptions that may occur when the try block and release the resource.

Guess you like

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