Java interview basics comprehensive interpretation of Java exceptions

Reprinted from: https://blog.csdn.net/a724888/article/details/80114720

Table of contents

Why use exceptions

Basic definition of exception

Abnormal system

First acquaintance with anomalies

Exceptions and errors

Exception handling

Tangled finally

throw : keyword also used by JRE

Exception call chain

Abnormal chaining

Custom exception

Unusual precautions

When finally meets return


This article introduces exceptions in Java in great detail, with almost no dead ends in 360 degrees.

It comprehensively introduces Java exceptions from the aspects of exception concepts, classification, usage, precautions and design.

Why use exceptions

First of all, we can make it clear that the exception handling mechanism can ensure the robustness of our program and improve system availability. Although we don't particularly like to see it, we can't help but recognize its status and role.
When there is no exception mechanism, this is how we handle it: We use the return value of the function to determine whether an exception has occurred (this return value is usually already agreed upon), and the program that calls the function is responsible for checking and analyzing the return value. Although exception problems can be solved, there are several drawbacks to doing so:

1. Easily confused . If it is agreed that the return value is -11111, it indicates an exception, then what if the final calculation result of the program is really -1111?
2. The code readability is poor . Mixing exception handling code with program code will make the code less readable.
3. Analyze exceptions by calling functions, which requires programmers to have a deep understanding of library functions.
The exception handling mechanisms provided in OO are a powerful way to provide code robustness. Using the exception mechanism can reduce the complexity of error handling code. Without exceptions, you would have to check for a specific error and handle it in many places in the program.

If you use exceptions, you don't have to check at the method call, because the exception mechanism will ensure that the error can be caught, and the error only needs to be handled in one place, the so-called exception handler.

This approach not only saves code, but also separates the code that outlines what to do during normal execution from the code that says "what to do if something goes wrong." In summary, the exception mechanism makes reading, writing, and debugging code more organized than previous error handling methods. (Excerpted from "Think in java").

This part of the content is selected from http://www.cnblogs.com/chenssy/p/3438130.html

Basic definition of exception

Exceptions are defined in "Think in Java" like this: Exception situations refer to problems that prevent the current method or scope from continuing to execute. It must be clear here: the exception code is wrong to some extent. Although Java has an exception handling mechanism, we cannot look at exceptions from a "normal" perspective. The reason for the exception handling mechanism is to tell you: something may or has already happened here. If an error occurs, your program has an abnormal situation, which may cause the program to fail!
So when will an exception occur? Only if the program cannot run normally in your current environment, that is to say, the program cannot solve the problem correctly, then it will jump out of the current environment and throw an exception. After throwing an exception, it does a few things first.
First, it will use new to create an exception object, then terminate the program at the location where the exception is generated, and pop up the reference to the exception object from the current environment. The exception handling mechanism will take over the program and start looking for an appropriate place to continue executing the program. This appropriate place is the exception handler.
In general, the exception handling mechanism is that when an exception occurs in the program, it forcibly terminates the program, records the exception information, and feeds this information back to us, so that we can determine whether to handle the exception.


Abnormal system

As can be seen from the picture above, Throwable is the super class of all errors and exceptions in the Java language (everything can be thrown). It has two subclasses: Error and Exception.

The Java standard library has some built-in general exceptions, and these classes have Throwable as the top-level parent class.

Throwable derives the Error class and Exception class.

Error: Instances of the Error class and its subclasses represent errors in the JVM itself . Errors cannot be handled by programmers through code, and Errors rarely occur. Therefore, programmers should pay attention to various exception classes under the branch where Exception is the parent class.

Exception: Exception and its subclasses represent various unexpected events sent when the program is running. It can be used by the Java exception handling mechanism and is the core of exception handling.

Generally speaking, we divide exception classes into two categories based on Javac's exception handling requirements.

Unchecked exception : Error and RuntimeException and their subclasses. When javac is compiled, it will not prompt or detect such exceptions, and it does not require the program to handle these exceptions. So if we want, we can write code to handle (using try...catch...finally) such exceptions, or not.
For these exceptions, we should correct the code instead of handling them through exception handlers. The reason for such exceptions is mostly due to problems with code writing. Such as dividing by 0 error ArithmeticException, wrong cast error ClassCastException, array index out of bounds ArrayIndexOutOfBoundsException, using an empty object NullPointerException, etc.
Checked exception : Exceptions other than Error and RuntimeException. javac forces programmers to prepare for such exceptions (using try...catch...finally or throws). In the method, either use a try-catch statement to capture it and process it, or use a throws clause to declare it, otherwise the compilation will not pass.
Such exceptions are generally caused by the running environment of the program. Because programs may be run in various unknown environments, and programmers cannot interfere with how users use the programs they write, programmers should always be prepared for such exceptions. Such as SQLException, IOException, ClassNotFoundException, etc.
What needs to be made clear is that checking and non-checking are for javac, so they are easy to understand and distinguish.

This part of the content is taken from http://www.importnew.com/26613.html

First acquaintance with anomalies

Exceptions are caused when executing a certain function, and functions are called hierarchically, forming a call stack, because as long as an exception occurs in a function, all its callers will be affected by the exception. When these affected functions output exception information, an exception tracing stack is formed.

The place where the exception first occurs is called the exception throwing point.

public class 异常 {
    public static void main (String [] args )
    {
        System . out. println( "----欢迎使用命令行除法计算器----" ) ;
        CMDCalculate ();
    }
    public static void CMDCalculate ()
    {
        Scanner scan = new Scanner ( System. in );
        int num1 = scan .nextInt () ;
        int num2 = scan .nextInt () ;
        int result = devide (num1 , num2 ) ;
        System . out. println( "result:" + result) ;
        scan .close () ;
    }
    public static int devide (int num1, int num2 ){
        return num1 / num2 ;
    }

//    ----欢迎使用命令行除法计算器----
//            1
//            0
//    Exception in thread "main" java.lang.ArithmeticException: / by zero
//    at com.javase.异常.异常.devide(异常.java:24)
//    at com.javase.异常.异常.CMDCalculate(异常.java:19)
//    at com.javase.异常.异常.main(异常.java:12)


//  ----欢迎使用命令行除法计算器----
//    r
//    Exception in thread "main" java.util.InputMismatchException
//    at java.util.Scanner.throwFor(Scanner.java:864)
//    at java.util.Scanner.next(Scanner.java:1485)
//    at java.util.Scanner.nextInt(Scanner.java:2117)
//    at java.util.Scanner.nextInt(Scanner.java:2076)
//    at com.javase.异常.异常.CMDCalculate(异常.java:17)
//    at com.javase.异常.异常.main(异常.java:12)


As can be seen from the above example, when the divide by 0 exception occurs in the devise function, the devise function will throw an ArithmeticException exception, so calling his CMDCalculate function cannot be completed normally, so an exception is also sent, and CMDCalculate's caller——main because CMDCalculate An exception is thrown and an exception occurs, thus tracing back to the bottom of the call stack.

This behavior is called exception bubbling. The purpose of exception bubbling is to find the nearest exception handler in the function where the exception currently occurs or the caller of this function. Since no exception handling mechanism is used in this example, the exception is eventually thrown to the JRE by the main function, causing the program to terminate.

The above code does not use the exception handling mechanism and can be compiled smoothly because the two exceptions are unchecked exceptions. But the following example must use the exception handling mechanism, because the exception is a checked exception.
In the code, I chose to use throws to declare exceptions and let the caller of the function handle any exceptions that may occur. But why only throws IOException? Because FileNotFoundException is a subclass of IOException, it is within the processing scope.

Exceptions and errors

Let’s see an example below

//错误即error一般指jvm无法处理的错误
//异常是Java定义的用于简化错误处理流程和定位错误的一种工具。
public class 错误和错误 {
    Error error = new Error();

    public static void main(String[] args) {
        throw new Error();
    }

    //下面这四个异常或者错误有着不同的处理方法
    public void error1 (){
        //编译期要求必须处理,因为这个异常是最顶层异常,包括了检查异常,必须要处理
        try {
            throw new Throwable();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
    //Exception也必须处理。否则报错,因为检查异常都继承自exception,所以默认需要捕捉。
    public void error2 (){
        try {
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //error可以不处理,编译不报错,原因是虚拟机根本无法处理,所以啥都不用做
    public void error3 (){
        throw new Error();
    }

    //runtimeexception众所周知编译不会报错
    public void error4 (){
        throw new RuntimeException();
    }
//    Exception in thread "main" java.lang.Error
//    at com.javase.异常.错误.main(错误.java:11)

}


Exception handling

When writing code to handle exceptions, there are 2 different ways to handle checked exceptions:

Use try...catch...finally block to handle it. Or , use the throws statement in the function signature to let the function caller handle it.
Let’s look at a few specific examples, including error, exception and throwable

The above example is a runtime exception and does not require explicit catching. 
The following example is a checkable exception that needs to be explicitly caught or thrown.

@Test
public void testException() throws IOException
{
    //FileInputStream的构造函数会抛出FileNotFoundException
    FileInputStream fileIn = new FileInputStream("E:\\a.txt");

    int word;
    //read方法会抛出IOException
    while((word =  fileIn.read())!=-1)
    {
        System.out.print((char)word);
    }
    //close方法会抛出IOException
    fileIn.close();
}


The usual way to deal with this is try catch finally

public class 异常处理方式 {
@Test
public void main() {
    try{
        //try块中放可能发生异常的代码。
        InputStream inputStream = new FileInputStream("a.txt");

        //如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
        int i = 1/0;
        //如果发生异常,则尝试去匹配catch块。
        throw new SQLException();
        //使用1.8jdk同时捕获多个异常,runtimeexception也可以捕获。只是捕获后虚拟机也无法处理,所以不建议捕获。
    }catch(SQLException | IOException | ArrayIndexOutOfBoundsException exception){
        System.out.println(exception.getMessage());
        //每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。

        //catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。

        //在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。

        //如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。

        //如果try中没有发生异常,则所有的catch块将被忽略。

    }catch(Exception exception){
        System.out.println(exception.getMessage());
        //...
    }finally{
        //finally块通常是可选的。
        //无论异常是否发生,异常是否匹配被处理,finally都会执行。

        //finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。
    }


A try must be followed by at least a catch or finally

   

 try {
        int i = 1;
    }finally {
        //一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
    }
}


The code following this method will not run when an exception occurs, even if the exception has been caught. Here is a strange example, using try catch finally again in catch

@Test
public void test() {
    try {
        throwE();
        System.out.println("我前面抛出异常了");
        System.out.println("我不会执行了");
    } catch (StringIndexOutOfBoundsException e) {
        System.out.println(e.getCause());
    }catch (Exception ex) {
    //在catch块中仍然可以使用try catch finally
        try {
            throw new Exception();
        }catch (Exception ee) {

        }finally {
            System.out.println("我所在的catch块没有执行,我也不会执行的");
        }
    }
}
//在方法声明中抛出的异常必须由调用方法处理或者继续往上抛,
// 当抛到jre时由于无法处理终止程序
public void throwE (){
//        Socket socket = new Socket("127.0.0.1", 80);

        //手动抛出异常时,不会报错,但是调用该方法的方法需要处理这个异常,否则会出错。
//        java.lang.StringIndexOutOfBoundsException
//        at com.javase.异常.异常处理方式.throwE(异常处理方式.java:75)
//        at com.javase.异常.异常处理方式.test(异常处理方式.java:62)
        throw new StringIndexOutOfBoundsException();
    }


In fact, some languages ​​can still continue to run after encountering an exception.

In some programming languages, when an exception is handled, the control flow will be restored to the point where the exception was thrown and then executed. This strategy is called: resumption model of exception handling (recovery exception handling mode). In Java, the execution flow is restored to processing
. The exception catch block is then executed. This strategy is called: termination model of exception handling (terminal exception handling mode)
"irresponsible" throws

Throws is another way of handling exceptions. It is different from try...catch...finally. Throws only declares the exceptions that may occur in the function to the caller, but does not handle them specifically.

The reason for adopting this kind of exception handling may be that the method itself does not know how to handle such exceptions, or that it is better for the caller to handle it, and the caller needs to be responsible for any exceptions that may occur.

public void foo() throws ExceptionType1 , ExceptionType2 ,ExceptionTypeN
     //foo内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常,或者他们的子类的异常对象。
}


Tangled finally

The finally block does not matter whether an exception occurs, as long as the corresponding try is executed, it will also be executed . There is only one way to keep the finally block from executing: System.exit() . Therefore, the finally block is usually used for resource release operations: closing files, closing database connections, etc.

Good programming practice is to open resources in the try block and clean up and release these resources in the finally block.

Things to note:

1. The finally block does not have the ability to handle exceptions. Exceptions can only be handled by catch blocks.

2. In the same try...catch...finally block, if an exception is thrown in try and there is a matching catch block, the catch block will be executed first, and then the finally block will be executed. If no catch block matches, finally is executed first, and then the external caller is searched for a suitable catch block.

3. In the same try...catch...finally block, if an exception occurs in try, and an exception is also thrown when handling the exception in the matching catch block, then the subsequent finally block will also be executed: first execute the finally block, and then look for it among the peripheral callers. A suitable catch block.

public class finally使用 {
    public static void main(String[] args) {
        try {
            throw new IllegalAccessException();
        }catch (IllegalAccessException e) {
            // throw new Throwable();
            //此时如果再抛异常,finally无法执行,只能报错。
            //finally无论何时都会执行
            //除非我显示调用。此时finally才不会执行
            System.exit(0);

        }finally {
            System.out.println("算你狠");
        }
    }
}


throw : keyword also used by JRE

throw exceptionObject

Programmers can also explicitly throw an exception manually through the throw statement. The throw statement must be followed by an exception object.

The throw statement must be written in the function. The place where the throw statement is executed is an exception throwing point. ==It is no different from the exception throwing point automatically formed by the JRE. ==

public void save(User user)
{
      if(user  == null) 
          throw new IllegalArgumentException("User对象为空");
      //......

}


Most of the following content is taken from http://www.cnblogs.com/lulipro/p/7504267.html

This article is very detailed and admirable. It is the most detailed article about anomalies that I have seen so far. It can be said that I stand on the shoulders of giants.

Exception call chain

Abnormal chaining

In some large-scale, modular software development, once an exception occurs in one place, it will lead to a series of exceptions like a domino effect. Assume that module B needs to call the method of module A to complete its own logic. If an exception occurs in module A, B will not be able to complete it and an exception will occur.

==But when B throws an exception, it will cover up the exception information of A, which will cause the source information of the exception to be lost. Exception chaining can chain exceptions from multiple modules so that exception information will not be lost. ==

Exception chaining: Construct a new exception object with an exception object as a parameter. The new exception object will contain information from the previous exception. This technology is mainly implemented by a function with Throwable parameters in the exception class. This is treated as a parameter exception, and we call it the root exception (cause).
Looking at the source code of the Throwable class, you can find that there is a Throwable field cause, which saves the root exception parameters passed during construction. This design is exactly the same as the node class design of the linked list, so it is natural to form a chain.

public class Throwable implements Serializable {
    private Throwable cause = this;

    public Throwable(String message, Throwable cause) {
        fillInStackTrace();
        detailMessage = message;
        this.cause = cause;
    }
     public Throwable(Throwable cause) {
        fillInStackTrace();
        detailMessage = (cause==null ? null : cause.toString());
        this.cause = cause;
    }

    //........
}


Let’s look at a more realistic example of an exception chain.

public class 异常链 {
    @Test
    public void test() {
        C();
    }
    public void A () throws Exception {
        try {
            int i = 1;
            i = i / 0;
            //当我注释掉这行代码并使用B方法抛出一个error时,运行结果如下
//            四月 27, 2018 10:12:30 下午 org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines
//            信息: Discovered TestEngines with IDs: [junit-jupiter]
//            java.lang.Error: B也犯了个错误
//            at com.javase.异常.异常链.B(异常链.java:33)
//            at com.javase.异常.异常链.C(异常链.java:38)
//            at com.javase.异常.异常链.test(异常链.java:13)
//            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
//            Caused by: java.lang.Error
//            at com.javase.异常.异常链.B(异常链.java:29)

        }catch (ArithmeticException e) {
            //这里通过throwable类的构造方法将最底层的异常重新包装并抛出,此时注入了A方法的信息。最后打印栈信息时可以看到caused by
            A方法的异常。
            //如果直接抛出,栈信息打印结果只能看到上层方法的错误信息,不能看到其实是A发生了错误。
            //所以需要包装并抛出
            throw new Exception("A方法计算错误", e);
        }

    }
    public void B () throws Exception,Error {
        try {
            //接收到A的异常,
            A();
            throw new Error();
        }catch (Exception e) {
            throw e;
        }catch (Error error) {
            throw new Error("B也犯了个错误", error);
        }
    }
    public void C () {
        try {
            B();
        }catch (Exception | Error e) {
            e.printStackTrace();
        }

    }

    //最后结果
//    java.lang.Exception: A方法计算错误
//    at com.javase.异常.异常链.A(异常链.java:18)
//    at com.javase.异常.异常链.B(异常链.java:24)
//    at com.javase.异常.异常链.C(异常链.java:31)
//    at com.javase.异常.异常链.test(异常链.java:11)
//    省略
//    Caused by: java.lang.ArithmeticException: / by zero
//    at com.javase.异常.异常链.A(异常链.java:16)
//            ... 31 more
}


Custom exception

If you want to customize the exception class, just extend the Exception class, so such custom exceptions are all checked exceptions. If you want to customize unchecked exceptions, extend from RuntimeException.

According to international practice, custom exceptions should always include the following constructor:

A no-argument constructor 
A constructor that takes a String parameter and passes it to the constructor of the parent class. 
A constructor that takes a String parameter and a Throwable parameter, and both are passed to the parent class constructor. 
A constructor that takes a Throwable parameter, and is passed to the parent class constructor. 
Below is the complete source code of the IOException class for reference.

public class IOException extends Exception
{
    static final long serialVersionUID = 7818375828146090155L;

    public IOException()
    {
        super();
    }

    public IOException(String message)
    {
        super(message);
    }

    public IOException(String message, Throwable cause)
    {
        super(message, cause);
    }

    public IOException(Throwable cause)
    {
        super(cause);
    }
}


Unusual precautions

Unusual precautions

When a subclass overrides a parent class's function with a throws declaration, the exceptions declared by its throws must be within the controllable scope of the parent class's exceptions - the exception handler used to handle the parent class's throws method must also apply to This throws method of the subclass. This is to support polymorphism.
For example, if the parent class method throws 2 exceptions, the subclass cannot throw 3 or more exceptions. The parent class throws IOException, and the subclass must throw IOException or a subclass of IOException.
As for why? I think maybe the following example can illustrate.

class Father
{
    public void start() throws IOException
    {
        throw new IOException();
    }
}

class Son extends Father
{
    public void start() throws Exception
    {
        throw new SQLException();
    }
}

 

/************假设上面的代码是允许的(实质是错误的)*************/

class Test
{
    public static void main(String[] args)
    {
        Father[] objs = new Father[2];
        objs[0] = new Father();
        objs[1] = new Son();

        for(Father obj:objs)
        {
        //因为Son类抛出的实质是SQLException,而IOException无法处理它。
        //那么这里的try。。catch就不能处理Son中的异常。
        //多态就不能实现了。
            try {
                 obj.start();
            }catch(IOException)
            {
                 //处理IOException
            }
         }
   }
}


==Java's exception execution process is thread independent, and there is no influence between threads==

Java programs can be multi-threaded. Each thread is an independent execution flow and independent function call stack. If the program has only one thread, an exception that is not handled by any code will cause the program to terminate. If it is multi-threaded, then an exception that is not handled by any code will only cause the thread where the exception is located to end.
In other words, exceptions in Java are thread-independent, and thread problems should be solved by the thread itself instead of being delegated to the outside, nor will it directly affect the execution of other threads.
Let’s see an example below

public class 多线程的异常 {
    @Test
    public void test() {
        go();
    }
    public void go () {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0;i <= 2;i ++) {
            int finalI = i;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            executorService.execute(new Runnable() {
                @Override
                //每个线程抛出异常时并不会影响其他线程的继续执行
                public void run() {
                    try {
                        System.out.println("start thread" + finalI);
                        throw new Exception();
                    }catch (Exception e) {
                        System.out.println("thread" + finalI + " go wrong");
                    }
                }
            });
        }
//        结果:
//        start thread0
//        thread0 go wrong
//        start thread1
//        thread1 go wrong
//        start thread2
//        thread2 go wrong
    }
}


When finally meets return

First, a fact that is not easy to understand:

Even if there are return, break, continue and other statements that change the execution flow in the try block, finally will be executed.

public static void main(String[] args)
{
    int re = bar();
    System.out.println(re);
}
private static int bar() 
{
    try{
        return 5;
    } finally{
        System.out.println("finally");
    }
}
/*输出:
finally
*/


When many people face this problem, they always summarize the order and rules of execution, but I think it is still difficult to understand. I have summarized a method myself. Use the following GIF to illustrate.

That is to say: as long as the returns in try...catch...finally can be executed, they are all executed. They jointly write the return value to the same memory address (assuming the address is 0×80), and the data executed later will overwrite the data executed first. , and the return value actually taken by the callee is the last one written. Then, according to this idea, the following example is not difficult to understand.

The return in finally will overwrite the return value in try or catch.

public static void main(String[] args)
    {
        int result;

        result  =  foo();
        System.out.println(result);     /2

        result = bar();
        System.out.println(result);    /2
    }

    @SuppressWarnings("finally")
    public static int foo()
    {
        trz{
            int a = 5 / 0;
        } catch (Exception e){
            return 1;
        } finally{
            return 2;
        }

    }

    @SuppressWarnings("finally")
    public static int bar()
    {
        try {
            return 1;
        }finally {
            return 2;
        }
    }


The return in finally will suppress (eliminate) the exception in the previous try or catch block

class TestException
{
    public static void main(String[] args)
    {
        int result;
        try{
            result = foo();
            System.out.println(result);           //输出100
        } catch (Exception e){
            System.out.println(e.getMessage());    //没有捕获到异常
        }

        try{
            result  = bar();
            System.out.println(result);           //输出100
        } catch (Exception e){
            System.out.println(e.getMessage());    //没有捕获到异常
        }
    }

    //catch中的异常被抑制
    @SuppressWarnings("finally")
    public static int foo() throws Exception
    {
        try {
            int a = 5/0;
            return 1;
        }catch(ArithmeticException amExp) {
            throw new Exception("我将被忽略,因为下面的finally中使用了return");
        }finally {
            return 100;
        }
    }

    //try中的异常被抑制
    @SuppressWarnings("finally")
    public static int bar() throws Exception
    {
        try {
            int a = 5/0;
            return 1;
        }finally {
            return 100;
        }
    }
}


The exception in finally will overwrite (eliminate) the exception in the previous try or catch

class TestException
{
    public static void main(String[] args)
    {
        int result;
        try{
            result = foo();
        } catch (Exception e){
            System.out.println(e.getMessage());    //输出:我是finaly中的Exception
        }

        try{
            result  = bar();
        } catch (Exception e){
            System.out.println(e.getMessage());    //输出:我是finaly中的Exception
        }
    }

    //catch中的异常被抑制
    @SuppressWarnings("finally")
    public static int foo() throws Exception
    {
        try {
            int a = 5/0;
            return 1;
        }catch(ArithmeticException amExp) {
            throw new Exception("我将被忽略,因为下面的finally中抛出了新的异常");
        }finally {
            throw new Exception("我是finaly中的Exception");
        }
    }

    //try中的异常被抑制
    @SuppressWarnings("finally")
    public static int bar() throws Exception
    {
        try {
            int a = 5/0;
            return 1;
        }finally {
            throw new Exception("我是finaly中的Exception");
        }

    }
}


The three examples above are all different from ordinary people’s coding thinking, so I suggest:

Don't use return in fianlly.
Don't throw exceptions in finally.
To reduce the task of finally, do not do other things in finally. It is most appropriate for the finally block to be used only to release resources.
Will try to write all returns at the end of the function instead of try...catch...finally.

 

Guess you like

Origin blog.csdn.net/harryptter/article/details/87874091