I often see the following pattern both in Java documentation and in other people's code when dealing with streams:
FileInputStream fis = null;
try {
fis = new FileInputStream("some.file");
// do something useful with fis
} finally {
if (fis != null) {
fis.close();
}
}
However I personally prefer a different pattern:
FileInputStream fis = new FileInputStream("some.file");
try {
// do something useful with fis
} finally {
fis.close();
}
I like the brevity of the latter and I think it's correct. But am I right about correctness? Is there an objective reason to prefer one over another?
Even if I write the examples pretty much how I would write such code in real life my pattern is still more concise. Compare the documentation approach:
public Object processFile(String fn) throws MyException {
FileInputStream fis = null;
try {
fis = new FileInputStream(fn);
return new Object(); // somehow derived from fis
} catch (FileNotFoundException e) {
throw new MySubExceptionForNotFound(e);
} catch (IOException e) {
throw new MySubExceptionForIoError(e);
} finally {
if (fis != null) {
IOUtils.closeQuietly(fis);
}
}
}
with my approach:
public Object processFile(String fn) throws MyException {
try {
FileInputStream fis = new FileInputStream(fn);
try {
return new Object(); // somehow derived from fis
} finally {
IOUtils.closeQuietly(fis);
}
} catch (FileNotFoundException e) {
throw new MySubExceptionForNotFound(e);
} catch (IOException e) {
throw new MySubExceptionForIoError(e);
}
}
Mine is one line shorter! :D
Interestingly my code does not change if you decide to use fis.close()
instead of IOUtils.closeQuietly()
while the "official" code will grow another 4 lines.
The second example that you have posted would not try/catch the possible errors that ... = new FileInputStream("...");
will return if it fails loading the file. In the first example though you automatically also catch the errors that the FileInputStream
gives.
I would personally go with the first one to have better error handling.
The second example does not compile unless you throw the exception from the method, because FileNotFoundException
is a checked exception.
Compile.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
FileInputStream fis = new FileInputStream("some.file");
The first example also does not compile, because you are missing the appropriate catch
block. Here is a compiling example.
import java.io.*;
public class Compile {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("some.file");
// do something useful with fis
if (fis != null) {
fis.close();
}
}
catch (FileNotFoundException fnf) {
}
catch (IOException ioe) {
}
finally {
}
}
}
Use try-with-resources :
try (FileInputStream fis = new FileInputStream("some.file")) {
// some code here
}
To answer the question of why the recommended pattern is the way it is, consider the fact that new FileInputStream(String)
throws a checked exception that you should probably catch; The
FileInputStream fis = null;
try {
fis = new FileInputStream("somefile.txt");
} catch (FileNotFoundException e) {
return false;
} finally {
if (fis != null) {
fis.close();
}
}
allows you to handle it in the same try/catch block as your other file-related exceptions. This has brevity and reduced nesting advantages over the following:
try {
FileInputStream fis = new FileInputStream("some.file");
try {
// do something useful with fis
} finally {
fis.close();
}
} catch (FileNotFoundException e) {
return false;
}
And if you're not catching the exception and just letting it propagate, then your suggestion is cleaner - however given the heavy use of checked exceptions in the IO libraries (including from class constructors), catching and handling an exception is common enough, and I think it makes sense to have just one pattern for tutorial purposes instead of showing someone a slightly different pattern each time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.