1

我正在从文件中读取数据,并且我想使用 try/catch 块来处理异常。我写了我的代码。但是,eclipse 只声明了我的扫描仪对象就给了我一个错误,我不得不将它初始化为 null。下面我写了我的代码的两个版本。哪个被认为是更好的做法?此外,使用 try/catch 块是否比仅在构造函数/函数头的末尾抛出异常更好?

代码版本#1:

java.util.Scanner in = null;

try {
    in = new java.util.Scanner (f);
    /* use scanner */
} catch (FileNotFoundException e) {
    System.err.println("File was not found. Make sure the file exist.");
    System.err.println("Message: " + e.getMessage());
} catch (IOException e) {
    System.err.println("File could not be opened.");
    System.err.println("Message: " + e.getMessage());
} finally {
    in.close();
}

代码版本#2:

try {
    java.util.Scanner in = new java.util.Scanner (f);
    /* use scanner */
    in.close();
} catch (FileNotFoundException e) {
    System.err.println("File was not found. Make sure the file exist.");
    System.err.println("Message: " + e.getMessage());
} catch (IOException e) {
    System.err.println("File could not be opened.");
    System.err.println("Message: " + e.getMessage());
}
4

4 回答 4

4

没有一个片段是正确的。如果 Scanner 构造函数抛出异常,第一个将导致 NullPointerException,因为它在调用 close() 之前不检查 null。

如果 try 块中出现任何异常,第二个将无法关闭扫描仪。

显然,第一个比第二个更接近正确的代码。

关于异常的最佳选择,这是正确性的问题。如果该方法可以正确处理异常(这意味着在处理异常后程序将继续按预期工作),它应该捕获它。如果它不能,它应该将它传播给调用者并让它处理它。

于 2013-04-20T12:45:43.347 回答
3

Java 7 引入了“Try with Resources”,以帮助防止由于在代码版本 #2 等实例中保持打开的资源而导致的内存泄漏,奖励:它易于使用。

    try( Scanner in = new Scanner( System.in ) ) {

    }

并做了。以上将在大括号之后自动关闭扫描器,无论大括号内部发生什么。

像往常一样,Catch 和 finally 块可能与 Try with Resources 一起出现,但并非必须如此。

于 2013-04-20T12:54:52.210 回答
1

in.close();在代码版本 #2 中,如果在文件不会关闭之前抛出异常。版本 #1 没有这个问题。

您可以使用 try with resource 组合这两个版本

try (java.util.Scanner in = new java.util.Scanner (new File("your file"))){
    /* use scanner */
} catch (FileNotFoundException e) {
    System.err.println("File was not found. Make sure the file exist.");
    System.err.println("Message: " + e.getMessage());
} catch (IOException e) {
    System.err.println("File could not be opened.");
    System.err.println("Message: " + e.getMessage());
}
//"in" will be closed automatically 
于 2013-04-20T12:44:53.987 回答
1

好吧,我认为第二个版本似乎很无奈。如果它确实在 try 块中引发了一些异常,则此代码将不会运行。

in.close();

为什么不把它放在 finally 块中?

于 2013-04-20T12:49:56.397 回答