解决多个io流需要关闭而重复嵌套try-catch-finally的问题

原文地址:https://blog.csdn.net/qq_34115899/article/details/81543497 

问题如图:

相信大多数人都见过如此状态,流多了需要层层关闭,需要层层加上try-catch,为保证下一个流能关闭又要加上finally,烦人!!

 

我们先来一个测试:

public class Test {
    public static void main(String[] args) {
        try {
            System.out.println("第一try");
            throw new Exception("异常");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("finally");
            try {
                throw new Exception("又是异常");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("会执行吗");
        }
    }
}


运行结果:

提取出重要信息,finally里面可以抓到异常后可以继续往下执行,也就是说finally里面try-catch抓到异常后也必须把这个代码块执行完。

那么有人就写了一个工具类,这种工具类对吗?

 

public class IOUtil {
    public static void close(Closeable... closeableList) {
        try {
            for (Closeable closeable : closeableList) {
                if (closeable != null){
                    closeable.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


然后

finally{
      IOUtil.close(is, os);
}


看似正确,实则错误!!

如果第一个流关闭的时候异常,那么第二个流close()就不可达,执行不到

这和并列写没区别,如下:

finally{

    try{

          is.close();

          os.close();   // 第一个流关闭出异常第二个流关闭就不可达,执行不到,等于没关

    } catch(Exception e) {

    }

}

 

那怎么办呢?不能写工具类吗?

不是不能写,而是这种写法是错误的,这种情况下应该把try-catch放在for循环里面,这样才能保证循环会依次关闭流

 

正确写法1:

public static void close(Closeable... closeableList) {
    for (Closeable closeable : closeableList) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


然后

finally{
      IOUtil.close(is, os);
}

 

正确解法2:

public <T extends java.io.Closeable> void close(T t) {
    try {
        if (t != null) {
            t.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}


然后

finally {
    close(in);
    close(raf);
    close(br);
}


哪怕其中有流关闭出了异常,也不会影响到其他流的关闭,finally{...}里面的东西是要执行完的

### 回答1: try catch是一种异常处理机制,用于捕获代码执行过程中可能出现的异常,并对其进行处理,以避免程序崩溃或产生不可预期的结果。 try语句块中包含可能会抛出异常的代码,如果在执行该代码时出现了异常,则会跳转到catch语句块中进行处理。catch语句块中的代码用于处理捕获到的异常,并对异常进行处理或输出错误信息。 try catch的基本用法如下: ```java try{ //可能会抛出异常的代码 } catch(Exception e){ //捕获到异常后的处理,例如输出错误信息 System.out.println("出现异常:" + e.getMessage()); } ``` 在try语句块中可以包含多个代码块,每个代码块都有可能抛出异常,可以在catch语句块中根据异常类型进行不同的处理。例如: ```java try{ //可能会抛出异常的代码块1 //可能会抛出异常的代码块2 } catch(IOException e){ //处理IO异常 } catch(NullPointerException e){ //处理空指针异常 } catch(Exception e){ //处理其他异常,例如输出错误信息 System.out.println("出现异常:" + e.getMessage()); } ``` 在catch语句块中还可以使用finally语句块,用于执行无论是否发生异常都必须执行的代码,例如关闭文件或网络连接等操作。例如: ```java try{ //可能会抛出异常的代码 } catch(Exception e){ //捕获到异常后的处理,例如输出错误信息 System.out.println("出现异常:" + e.getMessage()); } finally{ //无论是否发生异常都必须执行的代码,例如关闭文件或网络连接等操作 } ``` 总之,try catch语句块是Java异常处理机制的核心,能够有效地避免程序崩溃或出现不可预期的结果,提高程序的稳定性和健壮性。 ### 回答2: try catch是一种在编程中用于处理异常的机制。在程序运行过程中,可能会出现各种各样的异常情况,例如除以零、空指针引用等,这些异常情况如果没有进行处理,会导致程序的崩溃或者错误的结果输出。 使用try catch可以捕获并处理异常,避免程序崩溃和不正确的输出。try catch的基本用法是将可能抛出异常的代码块放在try中,然后在catch中处理异常。 当try代码块中的代码发生异常时,程序会立即跳转到catch代码块中执行。catch代码块中可以根据不同的异常类型,编写相应的处理逻辑。这样即使发生了异常,程序也可以通过catch代码块处理后继续执行,不会中断整个程序的运行。 另外,try catch可以嵌套使用,即在catch代码块中使用try catch来处理更细致的异常情况。这样可以对不同类型的异常进行不同的处理,保证程序的稳定性和正确性。 总之,try catch是一种异常处理机制,能够捕获并处理程序中的异常情况,避免程序崩溃或者错误的输出。通过合理使用try catch,可以提高程序的健壮性和可靠性,保证程序能够正常运行。 ### 回答3: try-catch是一种在编程中处理异常的机制。使用try-catch可以捕获并处理可能出现的异常,以便程序能够继续执行而不会被异常中断。 try-catch语句由try块和catch块组成。在try块中编写可能会引发异常的代码,catch块则用于捕获和处理这些异常。 当try块中的代码引发异常时,程序会立即转到catch块中,执行catch块中的代码,然后继续执行try-catch语句之后的代码,而不会让异常导致程序崩溃。 catch块可以定义一个或多个异常类型,用于捕获不同类型的异常。当异常类型与当前引发的异常类型匹配时,相应的catch块将被执行。 使用try-catch的好处是可以更加优雅地处理异常。通过合理使用try-catch,可以及时捕获异常并进行处理,避免程序崩溃或产生无法预知的错误结果。 另外,try-catch也可以用于记录异常信息或进行适当的恢复操作。在catch块中,我们可以打印异常信息或进行一些操作,以便定位和解决问题。 总之,try-catch是一种在编程中常用的异常处理机制。它能够帮助程序优雅地处理异常,保证程序的稳定性和可靠性。合理使用try-catch可以使程序更加健壮、可维护,并提升用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值