【问题标题】:In try with resources in java, what happens when there is an exception in close() when there is a catch block? [duplicate]在java中尝试资源时,当close()中有catch块时出现异常时会发生什么? [复制]
【发布时间】:2022-01-14 14:33:00
【问题描述】:

在这段代码中,当 br.close() 中出现异常时,catch 块会捕获它还是终止进程?

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class TryWithBlock {
    public static void main(String args[])
    {
        System.out.println("Enter a number");
        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
        {
            int i = Integer.parseInt(br.readLine());
            System.out.println(i);
        }
        catch(Exception e)
        {
            System.out.println("A wild exception has been caught");
            System.out.println(e);
        }
    }
}

【问题讨论】:

    标签: java exception


    【解决方案1】:

    来自docs

    try-with-resources 语句中声明的资源是 缓冲阅读器。声明语句出现在括号内 紧跟在 try 关键字之后。 Java 中的 BufferedReader 类 SE 7 及更高版本,实现接口 java.lang.AutoCloseable。 因为 BufferedReader 实例是在 try-with-resource 中声明的 语句,不管是否有try语句都会关闭 正常或突然完成(由于该方法 BufferedReader.readLine 抛出 IOException)。

    基本上相当于:

    BufferedReader br = new BufferedReader(new FileReader(System.in));
    try {
        int i = Integer.parseInt(br.readLine());
        System.out.println(i);
    } finally {
        br.close();
    }
    

    让我们尝试一下(这里是一个工作示例):

    //class implementing java.lang.AutoCloseable
    public class ClassThatAutoCloses implements java.lang.AutoCloseable {
    
        
        public ClassThatAutoCloses() {}
        
        public void doSomething() {
            
            System.out.println("Pippo!");
        }
        
        
        @Override
        public void close() throws Exception {
        
            throw new Exception("I wasn't supposed to fail"); 
            
        }
    
    }
    
    //the main class
    public class Playground {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            
            //this catches exceptions eventually thrown by the close
            try {
                
                try(var v = new ClassThatAutoCloses() ){
                    
                    v.doSomething();
                    
                }
            } catch (Exception e) {
                //if something isn't catched by try()
                //close failed will be printed
                System.err.println("close failed");
                e.printStackTrace();
            }
        }
    
    }
    
    //the output
    Pippo!
    close failed
    java.lang.Exception: I wasn't supposed to fail
        at ClassThatAutoCloses.close(ClassThatAutoCloses.java:26)
        at Playground.main(Playground.java:24)
    

    【讨论】:

    • 问题似乎不是问close()是否会在发生异常时被调用,而是如果close()本身抛出异常会发生什么。
    • 这种情况下会抛出异常
    • new FileReader(System.in) 在您的第一个示例中使用无效
    • 为什么要使用嵌套的 try 块?
    • @KMURALIKRISHNA 要捕获由资源发出的隐式 stop() 调用引发的异常,请尝试 try( ){}
    【解决方案2】:

    try-with-resources 语句中抛出的异常被抑制。在 try 块内抛出的异常会被传播。因此,在您的情况下,catch 块将捕获解析异常(如果有)。

    更多详情可以参考docs

    【讨论】:

    • OP 询问 close() 的异常情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多