关于finally代码块的抛出异常问题

之前面试被问道关于异常捕获的finally代码块作用,可能我们想到的会是在finally中进行一些资源关闭的操作。

常见的操作便是IO流这样的close操作:

public static void throwException(){
        File file = null;
        FileInputStream fis = null;
        try{
            file = new File("abc.txt");
            //可能抛出FileNotFoundException
            fis = new FileInputStream(file);
            fis.read();
        }catch(FileNotFoundException e){
            System.out.println("file not found");
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        } finally{
            //这里存在一个的异常,需要进行处理
            fis.close();
        }
    }

继续按照IDEA的提示处理,再次catch操作,代码会变为这样:

public static void throwException(){
        File file = null;
        FileInputStream fis = null;
        try{
            file = new File("abc.txt");
            //可能抛出FileNotFoundException
            fis = new FileInputStream(file);
            fis.read();
        }catch(FileNotFoundException e){
            System.out.println("file not found");
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        } finally{
            //这里存在一个的异常,需要进行处理
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

但是在Java核心技术书中,作者建议在finally块中尽量不要使用会抛出异常的资源回收语句。
也就是这里的close操作尽量不要出现异常,可是有些资源回收语句确实会抛出异常,此时应该怎么做呢?

我们可以观察到close操作抛出的异常是IOException,而前面的文件读取流也catch了该异常,所以我们可以将两个异常归并到一起,然后代码就变成这样了:

public static void throwException(){
        File file = null;
        FileInputStream fis = null;
        try{
            try {
                file = new File("abc.txt");
                //可能抛出FileNotFoundException
                fis = new FileInputStream(file);
                fis.read();
            }  finally {
                fis.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

如果你认为是没有异常了,那我们执行一下看:
在这里插入图片描述
我们可以看到这里抛出空指针异常,分析代码我们可以发现fis可能为空,所以需要在close之前去判断一下它,防止出现空指针这样的异常。

public static void throwException(){
        File file = null;
        FileInputStream fis = null;
        try{
            try {
                file = new File("abc.txt");
                //可能抛出FileNotFoundException
                fis = new FileInputStream(file);
                fis.read();
            }  finally {
                if(fis != null){
                    fis.close();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

还有一种做法就是,我们可以将抛出的异常写到日志中去,在catch语句块中写入。

总结:

1、在捕获异常的时候我们要清楚自己代码可能抛出的异常,不要只按照IDE提示的处理策略去处理,那样可能导致整个代码很乱,要试着去将异常归纳起来处理;
2、对于可能空的变量操作,我们一定要去做if判断之后再进行响应的操作;
3、对于异常处理,我们也可以通过日志写入的方式做好处理;

发布了49 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41999455/article/details/103325932