Is it a good practice to set stream references to null after closing them? Would this release resources in any way?
Example:
BufferedReader input= new BufferedReader(new FileRea开发者_运维知识库der("myfile.txt"));
// code
input.close();
input = null;
// possible more code
No, it's bad practice. IMO, you should even consider making the variable final
.
Resource handling should be handled in the standard acquire(); try { use(); } finally { release(); }
manner. In this case:
final Reader rawIn = new FileReader("myfile.txt"); // Character encoding??
try {
BufferedReader in = new BufferedReader(rawIn);
// code
} finally {
rawIn.close();
}
Actually this code picks up whatever character encoding is set as default. I suggest being explicit with either a particular hard-coded charset or Parameterise from Above.
final InputStream rawIn = new FileInputStream("myfile.txt");
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(rawIn, "UTF-8")
);
// code
} finally {
rawIn.close();
}
You should not create the wrapper streams/readers outside of the try block (and before the resource assignment) because they might throw. Similarly their close might throw (this was actually a bug in BufferedOutputStream
which could throw on flush
). Some input streams may have other resources so you need two try { ... finally { x.close(); }
s.
For output, you generally should flush
in the normal course of events. But generally don't in exceptional cases. Indeed close
usually does a flush
, therefore you should not close them in the exceptional case. If decorators both flush
and have resources, then you'll have to grin and bare it.
There are highly infrequent occasions when nulling out is a good idea. For instance if a variable is the sole reference to a large object and you are going to create a new large object to assign to it, it may be best to clear the reference to allow the old to be reclaimed before allocating the new.
Not needed. Just input.close()
is enough. Remember its always wise to do this inside a finally
block. And before calling close()
its better to do a null check like this
finally{
if(input!=null){
input.close();
}
}
It may make the Stream object itself eligible for garbage collection, but
- In most cases it will pass out of scope right afterwards anyway
- the amount of memory thus "released" is utterly insignificant
Unless you're manually managing a pool of rosources (handling your own memory), it's not necessary to null the input stream. Ideally, whatever function you're in is small, and references to the object will die as the object goes out of scope, marking it for garbage collection anyway.
I mention pooling resources, as if you naively close the stream without nulling the object, you could accidentally hold on to a reference of the object that you don't actually need.
No, it is not. The close()
already frees up the resource. The normal practice is the following:
Resource resource = null;
try {
resource = new Resource();
// ...
} finally {
if (resource != null) try { resource.close(); } catch (ResourceException logOrIgnore) {}
}
Where Resource
can be any external resource you'd like to use, such as InputStream
, OutputStream
, Reader
and Writer
of Java IO API, but also for example Connection
, Statement
and ResultSet
of JDBC API.
The memory is a non-issue in well designed code. If the code leaves the method block, it's already eligible for GC.
You can refactor the close()
to an utility method like:
public static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (ResourceException logOrIgnore) {
// Log it?
}
}
}
which you can use as follows:
} finally {
close(resource);
}
The Apache Commons provides several utility methods like that.
In this case it is not needed, the garbage collector will collect it.
But it is not always a bad practice to assign null
. Read Item 6 from Effective Java, chapter 2
精彩评论