try catch 循环问题的真相

try catch在编码过程中经常使用,为了捕获可预见的异常,保证程序继续运行。

如果遇到循环处理逻辑,try catch应该放在循环内、还是循环外呢?

我这里记录一下:

通常的一种说法:

try catch放在循环内,异常自己捕获处理。其他循环可以继续执行。

放在循环外,循环体就视为一个整体,一旦发生异常,就不执行。

// 放在外部
try {
    for(int i=1;i<4;i++){
        int num = 1/0;
        System.out.println("i="+i);
    }
    System.out.println("try");
}catch (ArithmeticException ex){
    System.err.println("java.lang.ArithmeticException: / by zero");
}
System.out.println("go");

执行结果:直接报错,跳出try块。继续运行下面的代码。

 

// 放在内部
for(int i=1;i<4;i++){
    try {
        int num = 1/0;
        System.out.println("try");
    }catch (ArithmeticException ex){
        System.err.println("java.lang.ArithmeticException: / by zero");
    }
    System.out.println("i="+i);
}
System.out.println("go");

执行结果:

由于异常被捕获,会抛出异常。跳出try块。循环体内代码继续执行。

 

好戏才刚开始~

// 放在内部
for(int i=1;i<4;i++){
    try {
        File file = new File("D://test"+i);
        FileUtils.cleanDirectory(file);
        System.out.println("try");
    } catch (IOException e) {
        System.err.println("IOException"+i);
    }
    System.out.println("i="+i);
}

我的D盘,创建了一个test1、test3文件夹。

按照刚才的逻辑,虽然没有test2文件夹,会导致报错。但循环会继续执行。

执行结果:

Why?? 说好的循环内部try catch继续执行呢!

观察错误,发现异常其实未被程序捕获,我们被表象迷惑了!!

让我们看看源码:

/**
     * Cleans a directory without deleting it.
     *
     * @param directory directory to clean
     * @throws IOException              in case cleaning is unsuccessful
     * @throws IllegalArgumentException if {@code directory} does not exist or is not a directory
     */
    public static void cleanDirectory(final File directory) throws IOException {
        final File[] files = verifiedListFiles(directory);

        IOException exception = null;
        for (final File file : files) {
            try {
                forceDelete(file);
            } catch (final IOException ioe) {
                exception = ioe;
            }
        }

        if (null != exception) {
            throw exception;
        }
    }

虽然这个清空目录文件的方法,抛出的是IOException异常,我们catch也处理了。

但是它还主动抛出了其他的异常!!比如这里的运行时异常:IllegalArgumentException

/**
     * Lists files in a directory, asserting that the supplied directory satisfies exists and is a directory
     * @param directory The directory to list
     * @return The files in the directory, never null.
     * @throws IOException if an I/O error occurs
     */
    private static File[] verifiedListFiles(File directory) throws IOException {
        if (!directory.exists()) {
            final String message = directory + " does not exist";
            throw new IllegalArgumentException(message);
        }

        if (!directory.isDirectory()) {
            final String message = directory + " is not a directory";
            throw new IllegalArgumentException(message);
        }

        final File[] files = directory.listFiles();
        if (files == null) {  // null if security restricted
            throw new IOException("Failed to list contents of " + directory);
        }
        return files;
    }

 

于是我们将代码改为:

    // 放在内部
    for(int i=1;i<4;i++){
        try {
            File file = new File("D://test"+i);
            FileUtils.cleanDirectory(file);
            System.out.println("try");
        } catch (IOException e) {
            System.err.println("IOException"+i);
        } catch (IllegalArgumentException e){
            System.err.println("IllegalArgumentException"+i);
        }
        System.out.println("i="+i);
    }

执行结果: 虽然报错,但循环继续执行了。

提示:(更加粗暴的方式,就是直接抛出Exception错误,妥妥的都能捕获。运行时异常也是继承Exception的。)

 

 

END O(∩_∩)O

 

 

 

 

 

 

 

 

 

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值