我正在读取文件,我想使用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());
}
答案 0 :(得分:4)
没有一个片段是对的。如果Scanner构造函数抛出异常,第一个将导致NullPointerException,因为它在调用close()之前不检查null。
如果try块中出现任何异常,则第二个无法关闭扫描仪。
第一个显然比第二个更接近正确的代码。
关于异常的最佳方式,这是正确性的问题。如果该方法可以正确处理异常(这意味着程序将在处理异常后继续按预期工作),它应该捕获它。如果它不能,它应该将它传播给调用者并让它处理它。
答案 1 :(得分:2)
Java 7引入了“尝试使用资源”来帮助防止由代码版本#2等实例中的资源打开导致的内存泄漏,奖励:它易于使用。
try( Scanner in = new Scanner( System.in ) ) {
}
完成了。无论矫正器内部发生什么,上面都会自动关闭括号后的扫描仪。
Catch和Finally块可能像往常一样与Try with Resources一起出现,但不必如此。
答案 2 :(得分:1)
在代码版本#2中,如果在in.close();
文件关闭之前将抛出异常。版本#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
答案 3 :(得分:1)
嗯,我认为第二个版本似乎无能为力。如果它在try块中引发了一些异常,则该代码将不会运行。
in.close();
为什么不把它放在finally块中?