Detailed explanation of exception architecture in Java (throw, throws, try-catch, finally, custom exceptions)


Table of contents

1. The concept of abnormality

2. Abnormal architecture

3. Exception handling

Exception handling ideas

LBYL:Look Before You Leap

EAFP: It's Easier to Ask Forgiveness than Permission

exception throw

Exception catching

reminder statement throws

 try-catch capture processing

The role of finally

4. Custom exception class


1. The concept of abnormality

There is a saying that goes well, "Programmers are either writing bugs or fixing bugs." In daily development, programmers rack their brains to write perfect code, but it is inevitable that errors will occur during the running of the program. Encountered some strange problems. These problems and bugs are always difficult to control. Using human thinking is obviously a perfect logical process, but the results produced by the compiler will always be very different from our expectations. In Java, we will Abnormal behaviors that occur during program execution are called abnormalities, such as arithmetic exceptions< a i=4>Ah, Array out-of-bounds exceptionAh, Null pointer exception Ah, these all belong to the scope of exceptions, we collectively call them exceptions

        System.out.println(10 / 0);
        // 执行结果Exception in thread "main" java.lang.ArithmeticException
        
        int[] arr1 = {1, 2, 3};
        System.out.println(arr1[100]);
        // 执行结果Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
        
        int[] arr2 = null;
        System.out.println(arr2.length);
        // 执行结果Exception in thread "main" java.lang.NullPointerException

And we can seeIn Java, there are corresponding classes to describe different exceptions


2. Abnormal architecture

In fact, there are many types of exceptions. In order to deal with different exceptions or errors, Java provides a very large exception system for programmers to better maintain the security of the code, as shown in the figure below

Exceptions may occur in the compilation phase or in the running phase, so we can classify them according to the time period in which they occur:

  • Compile-time exceptions, also called checked exceptions
  • Runtime exceptions, also called unchecked exceptions 

However, problems caused by misspelling words and problems with our program are not exceptions.


3. Exception handling

It is not strange that there are exceptions in the code, but after an exception occurs, we need to notify the programmer in time to make changes. We have two ideas for handling exceptions.

Exception handling ideas

LBYL:Look Before You Leap

That is to say, we fully check the exceptions before operation, which is a defensive type in advance. For example, when we design a When making a game, we need to develop processing mechanisms and avoidance mechanisms for every error that may occur

        boolean ret = false;
        ret = loginGame();
        if (!ret) {
            //处理登陆游戏错误;
            return;
        }
        ret = startMatch();
        if (!ret) {
            //处理匹配错误;
            return;
        }
        ret = conGame();
        if (!ret) {
            //处理游戏确认错误;
            return;
        }
        ret = choiceChar();
        if (!ret) {
            //处理选择英雄错误;
            return;
        }
        ret = loading();
        if (!ret) {
            //处理载入游戏错误;
            return;
        }

But this kind of processing will have a flaw: the normal process and error handling process codes are mixed together, making the overall code confusing

EAFP: It's Easier to Ask Forgiveness than Permission

The main problem solved by this kind of thinking is not how to avoid exceptions in advance, but how to respond reasonably afteranomalies occur

        try {
            loginGame();
            startMatch();
            conGame();
            choiceChar();
            loading();

        } catch (loginGame异常) {
            //处理登陆游戏错误;
        } catch (startMatch异常) {
            //处理匹配错误;
        } catch (conGame异常) {
            //处理游戏确认错误;
        } catch (choiceChar异常) {
            //处理选择英雄错误;
        } catch (loading异常) {
            //处理载入游戏错误;
        }

The core mechanism for exception handling in Java is EAFP. There are 5 commonly used exception handling keywords in Java: a>

  • throw
  • try
  • catch
  • final
  • throws

exception throw

In Java, you can use the throw keyword to throw a specified exception object and inform the caller of the error message. The specific syntax is as follows:

thrownewXXXException("Cause of exception")   

Example: 

    public static int getElement(int[] array, int index){
        if(null == array){
            throw new NullPointerException("传递的数组为null");
        }
        if(index < 0 || index >= array.length){
            throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");
        }
        return array[index];
    }
    public static void main(String[] args) {
        int[] array = {1, 2, 3};
        getElement(array, 3);
    }

 Notice:

  1. throw  must be written inside the method body
  2. The object thrown must be Exception or Exception Subclass object
  3. If RunTimeException or RunTimeException  is thrown If the subclass is a subclass, it does not need to be processed and can be directly handed over to JVM for processing
  4. If a compile-time exception is thrown, the user must handle it, otherwise the compilation will not pass.
  5. Once an exception is thrown, the subsequent code will not be executed.

Exception catching

Exception catching refers to our handling of exceptions. Usually we have two ways to handle them:

  • Exception declaration throws
  • try-catch capture processing

reminder statement throws

is after the parameter list when the method is declared. When a compile-time exception is thrown in the method and the user does not want to handle the exception, you can use throwsThrow the exception to the caller of the method for handling. That is to sayThe current method does not handle exceptions, remind the caller of the method to handle exceptions.

Syntax format:

ModifierReturn value type Method name (Parameter list) throws Exception type 1, exception type 2...{

}

public class Config {
    File file;
    /*
    FileNotFoundException : 编译时异常,表明文件不存在
    此处不处理,也没有能力处理,应该将错误信息报告给调用者,让调用者检查文件名字是否给错误了
    */
    public void OpenConfig(String filename) throws FileNotFoundException {
        if (filename.equals("config.ini")) {
            throw new FileNotFoundException("配置文件名字不对");
        }
        // 打开文件
    }
}

Precautions:

  • throws  must follow the method parameter list
  • The problem thrown must be Exception or Exception Subclass object
  • If multiple exceptions are thrown inside the method, throws  must be followed by multiple exception types, separated by commas. If Throwing multiple exception types has a parent-child relationship, just declare the parent class directly
  • When calling an exception method that is declared to throw, the caller must handle the exception or continue to use throws throws

Example: 

class Config {
    File file;
    // FileNotFoundException 继承自 IOException
    public void OpenConfig(String filename) throws IOException {
        if(filename.endsWith(".ini")){
            throw new IOException("文件不是.ini文件");
        }
        if(filename.equals("config.ini")){
            throw new FileNotFoundException("配置文件名字不对");
        }
        // 打开文件
    }
    public void readConfig(){
    }
    public void openConfig(String s) {
    }
    public static void main(String[] args) throws IOException {
        Config config = new Config();
        config.openConfig("config.ini");
    }
}

 try-catch capture processing

The throws we mentioned just nowthrows  do not handle exceptions. They just report the exceptions to the caller and let the caller go. Handling, and if you want to actually handle the exception, you need to use try-catch.

The general usage syntax of try-catch is as follows, wherecatch: there can be one or more Multiple, allocated according to specific needs, finallymay or may not be available, but if yesfinallyfinally The code in a> will not cause exception:try will definitely be executed, and the code in

try{
    // 将可能出现异常的代码放在这里
    }catch(要捕获的异常类型 e){
        // 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时
        //或者是try中抛出异常的基类时,就会被捕获到
        //对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
    }catch(异常类型 e){
        // 对异常进行处理
    }finally{
        // 此处代码一定会被执行到
    }
}

Example:

class Config {
    File file;
    public void openConfig(String filename) throws FileNotFoundException{
        if(!filename.equals("config.ini")){
            throw new FileNotFoundException("配置文件名字不对");
        }
        // 打开文件
    }
    public void readConfig(){
    }
    public static void main(String[] args) {
        Config config = new Config();
        try {
            config.openConfig("config.txt");
            System.out.println("文件打开成功");
        } catch (IOException e) {
        // 异常的处理方式
        //System.out.println(e.getMessage()); // 只打印异常信息
        //System.out.println(e); // 打印异常类型:异常信息
            e.printStackTrace(); // 打印信息最全面
        }
        // 一旦异常被捕获处理了,此处的代码会执行
        System.out.println("异常如果被处理了,这里的代码也可以执行");
    }
}

Notice:

  •  try The code after the exception position in the block will not be executed
  •  If the exception type thrown does not match the exception type when catch, that is, the exception will not be successfully caught and will not be handled. , continue to be thrown out until the JVM interrupts the program after receiving it - exceptions are captured according to type
  •  Multiple different exception objects may be thrown in try , so you must use multiple catchTo capture----that is, multiple exceptions, multiple captures
  • If there is a parent-child relationship between exceptions, the subclass exception must be caught firstcatch, and the parent class exception is followed< a i=3>catch, otherwise syntax error

The role of finally

When writing a program, some specific codes need to be executed regardless of whether an exception occurs in the program, such as resources opened in the program: network connections, database connections, IO streams, etc., when the program exits normally or abnormally, Resources must be recycled. In addition, because exceptions will cause program jumps, some statements may not be executed. finally is used to solve this problem.

Regarding exception handling methods, there are many types of exceptions, and we have to decide according to different business scenarios.

  • For more serious problems (such as scenarios related to money calculation), the program should be crashed directly to prevent more serious consequences.
  • For less serious problems (most scenarios), error logs can be recorded and programmers can be notified in a timely manner through the monitoring alarm program.
  • For problems that may be recovered (network-related scenarios), you can try again
  • In our current code, we adopt the simplified second method. The error log we record is the method call information where exceptions occur, which can quickly allow us to find the location of exceptions. In the future, we will adopt A more complete way to record exception information

4. Custom exception class

Although Java has built-in rich exception classes, it cannot fully represent some exceptions encountered in actual development. At this time, we need to maintain an exception structure that conforms to our actual situation. Custom exceptions are usually inherited. sinceException or RunTimeException

  • Exceptions inherited from Exception are checked exceptions by default
  • Exceptions inherited from RunTimeException are unchecked exceptions by default

Specific methods:

  1. Customize the exception class and then inherit from Exception or RunTimeException
  2. Implement a constructor with String type parameters. Parameter meaning: the reason for the exception

For example, we implement a user login function: 

class UserNameException extends Exception {
    public UserNameException(String message) {
        super(message);
    }
}
class PasswordException extends Exception {
    public PasswordException(String message) {
        super(message);
    }
}
class LogIn {
    private String userName = "admin";
    private String password = "123456";
    public static void loginInfo(String userName, String password)
            throws UserNameException,PasswordException{
        if (!userName.equals(userName)) {
            throw new UserNameException("用户名错误!");
        }
        if (!password.equals(password)) {
            throw new PasswordException("用户名错误!");
        }
        System.out.println("登陆成功");
    }
    public static void main(String[] args) {
        try {
            loginInfo("admin", "123456");
        } catch (UserNameException e) {
            e.printStackTrace();
        } catch (PasswordException e) {
            e.printStackTrace();
        }
    }
}



 That’s it for this sharing. I hope my sharing can be helpful to you. I also welcome everyone’s support. Your likes are the biggest motivation for bloggers to update! If you have different opinions, you are welcome to actively discuss and exchange in the comment area, let us learn and make progress together! If you have relevant questions, you can also send a private message to the blogger. The comment area and private messages will be carefully checked. See you next time

Guess you like

Origin blog.csdn.net/m0_69519887/article/details/134593214