捕获时为什么要使用IOexception而不是Exception?

时间:2013-12-17 21:00:23

标签: java exception

我似乎无法正确地说出这一点,以便搜索引擎获得任何有意义的结果。

try{
    BufferedReader reader = new BufferedReader( new FileReader("foo.bar") );
}
catch(Exception e){
    println( e.getMessage() );
}

所以FileReader只会抛出FileNotFoundException,据我所知它是IOException,这是一个例外。有人可以解释为什么我会抓住FileNotFoundExceptionIOException而不是仅指定通用“异常”而不必导入异常(即导入java.io.FileNotFoundException;)?它是否严格用于可读性?< / p>

我使用所有三个名字捕获了异常,我找不到区别。

编辑:--------------------

private BufferedReader askUserForFile(String prompt){
        BufferedReader rd = null;
        while(rd == null){
            try{
                String filename = readLine(prompt);
                rd = new BufferedReader( new FileReader(filename) );
            }
            catch(Exception e){
                println(e.getMessage());
            }
        }
        return rd;
    }

6 个答案:

答案 0 :(得分:7)

Exception是所有异常的母亲,包括所有RuntimeException子类。当你指定捕获它时,你会在网上获得比你想要的更多的鱼,比如NullPointerException s,IllegalArgumentException等等。

虽然在代码中的某个时刻捕获通用Exception 是正确的事情,但在任何较低层捕获它几乎肯定是错误的并且可能会损害应用程序的行为

在Java中学习的更重要的技能不是如何捕获异常,而是如何不捕获它们,而是让它们向上传播调用堆栈,朝向异常障碍,代码中的一个常见位置,其中捕获并统一处理所有错误(通常通过记录,回滚事务等)。

答案 1 :(得分:6)

不同之处在于try块的代码中可能存在其他问题,这些问题可能引发其他类型的Exception,包括RuntimeException的子类(不必声明)。< / p>

如果您只是抓住Exception,那么您将捕获所有其他错误,这可能会隐藏不同的问题。此外,catch块中的代码不能假定由于IOException而发生异常,因为将捕获任何类型的异常。

答案 2 :(得分:3)

作为dkatzel答案的后续内容,让我们假设您开始从同一个try块中的文件中读取文件,该文件告诉您要使用的选项数组中的哪个值:

String toPrint = {"Hi", "World", "I'm", "A", "String", "Array"};
try{
    BufferedReader reader = new BufferedReader( new FileReader("foo.bar") );
    String line = reader.readLine();
    System.out.println(toPrint[Integer.parseInt(line)]);

}
catch(Exception e){
    println( e.getMessage() );
}

现在你完全不知道除了堆栈跟踪之外到底出了什么问题。您无法处理任何可修复的问题。如果第一行不是整数,则无法在代码中告知文件是否不存在(FileNotFoundException),您无权访问该文件(IOException)。 NumberFormatException),或者数字大于数组长度(ArrayIndexOutOfBoundsException)。如果您想要读取该数字时想要打印默认值,则可以使用NumberFormatException来打印该值而不必退出整个程序。

我承认这是一个非常人为的例子,但它应该让你解释为什么捕捉Exception是坏事。 Marko也有一个非常好的答案,声明通常最好让异常传播(特别是使用RuntimeException s)而不是创建一堆乱码来试图处理可能发生的每一个问题。 / p>

答案 3 :(得分:1)

如果您想使用不同的例外执行不同的操作,该怎么办?您可以为IOException创建一个catch块,例如,让它显示一个消息框。然后为FileNotFoundException创建另一个catch块并使其创建一个新文件并尝试再次打开它,甚至重新抛出异常。希望我能正确解释自己。干杯!

答案 4 :(得分:0)

原因是无论何时编程,您都必须考虑所有可能性,并且针对特定错误执行某些操作非常有用。 Exception是捕获错误的所有方法,并且将处理所有异常。 IOException将捕获任何IO异常,因此它将处理未找到的文件和其他IO异常(如EOFException)相同。 FileNotFoundException只会捕获未找到文件的异常,因此您可以处理它而不是仅记录它。

会发生一些错误,并且能够处理每个案例使程序保持运行。在这种情况下,找不到文件可以让您选择另一个文件,以便程序不会崩溃并处理这种情况。

答案 5 :(得分:0)

  

FileNotFoundExceptionIOExceptionException

你是对的。但是如果您捕获Exception个对象,您将捕获由代码触发的任何异常,而不仅仅是FileNotFound异常。

让我们说你的代码可以抛出多种异常:

try {
    /*
     * Code, code and more code
     */
} catch(ExceptionType1 e) {
        System.err.println("Something went wrong! It is a type 1 exception");
} catch(ExceptionType2 e) {
        System.err.println("Something went wrong! It is a type 2 exception");
} catch(Exception e) {
        System.err.println("Something went wrong! It is not any of the known exception types");
}

将上述可能性与此相比较:

try {
    /*
     * Code, code and more code
     */
} catch(Exception e) {
        System.err.println("Something went wrong! Can be exception type 1, 2 or something else");
}

如您所见,区分异常类型可以帮助您了解代码中出现的问题。