简体   繁体   English

Java扫描仪良好做法

[英]Java Scanner Good Practice

I am reading from a file, and I want to handle the exceptions using try/catch blocks. 我正在读取文件,并且想使用try / catch块处理异常。 I wrote my code. 我写了我的代码。 However, eclipse gave me an error with just declaring my scanner object, and I had to initialize it to null. 但是,eclipse仅声明了我的扫描器对象就给了我一个错误,我不得不将其初始化为null。 Below I wrote two versions of my code. 下面,我编写了两个版本的代码。 Which is considered a better practice? 哪个被认为是更好的做法? Also, is it better to use try/catch block than just throw the exception at the end of the constructor/function header? 另外,使用try / catch块比在构造函数/函数标头的末尾抛出异常更好吗?

Code version #1: 代码版本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();
}

Code version #2: 代码版本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());
}

None of the snippets is right. 没有一个片段是正确的。 The first one will cause a NullPointerException if the Scanner constructor throws an exception, because it doesn't check for null before invoking close(). 如果Scanner构造函数引发异常,则第一个将引发NullPointerException,因为在调用close()之前它不会检查null。

The second one fails to close the scanner in case of any exception in the try block. 如果try块中有任何异常,第二个扫描器将无法关闭扫描仪。

The first one is closer to the correct code than the second one, obviously. 显然,第一个比第二个更接近正确的代码。

Regarding what is best regarding the exception, it's a matter of correctness. 关于什么是最好的例外情况,这是正确性的问题。 If the method can handle the exception correctly (and that means the program will continue to work as expected after the exception is handled), it should catch it. 如果该方法可以正确处理异常(这意味着在处理异常后程序将继续按预期工作),则应捕获该异常。 If it can't, it should propagate it to the caller and let it handle it. 如果不能,则应将其传播给调用方并让其处理。

Java 7 introduced 'Try with Resources' to help prevent memory leaks caused by resources left open in instances like code version #2, bonus: it's simple to use. Java 7引入了“尝试使用资源”功能,以防止由于在代码版本#2中获得的资源未打开而导致的内存泄漏,附赠:使用简单。

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

    }

And done. 并做了。 The above will automatically close the Scanner after the braces, no matter what happens inside the braces. 无论括号内发生什么,以上内容都会在括号后自动关闭扫描仪。

Catch and Finally blocks may appear in conjunction with Try with Resources, as usual, but don't have to. 通常,“捕获”和“最终”块可能会与“尝试使用资源”一起出现,但不必这样做。

In code version #2 if exception will be thrown before in.close(); 在代码版本2中,如果将在in.close();之前引发异常in.close(); file wont be closed. 文件不会关闭。 Version #1 doesn't have that problem. 版本1没有这个问题。

You can combine these two version using try with resource 您可以将try和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 

Well, I think the second version seems helpless. 好吧,我认为第二个版本似乎无能为力。 If it does throw some exception in the try block, this code won't run. 如果确实在try块中引发了某些异常,则此代码将不会运行。

in.close();

Why not put it in a finally block? 为什么不把它放到最后一块呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM