I have a function and locally I have some pointers for file handling, reading zip files (using java.util.zip.ZipFile
), streams etc. I must enclose all this work in a try{...}catch(...){...}
statement, but when this fails I must close all the open pointers one by one according to the type of error. Can I avoid this by simply terminating the function through a return?
The pointers are declared locally within the function, so I think they should be destroyed at the end of the function like any declared variable, but being pointers they make use of reserved memory space, so I don't know what happens with that pointer at the end of the function without closing it, I do not know if it is destroyed, closed or remains in memory inaccessible within the thread.
I have searched for information but have not accomplished much. Does anyone know more about this topic?
Are the pointers closed at the end of the local declaration?
Terminology: Java doesn't have pointers. They are called references.
Short answer: No.
I must enclose all this work in a
try{...}catch(...){...}
statement, but when this fails I must close all the open pointers one by one according to the type of error.
Partly correct. You should not be closing resources in catch
blocks. There is a better way. In fact there are two ways to use try
to achieve what you are trying to do.
Prior to Java 7, you would do this:
SomeHandle h;
try {
h = /* open it */
...
} catch (...) {
...
} finally {
// close the resources
if (h != null) {
h.close();
}
}
From Java 7 onwards you can write this more simply using try with resources syntax:
try (Handle h = /* open it */) // <<-- resource declarations
{
...
} catch (...) {
...
}
The resources are closed automatically in the reverse order that they are declared. The try-with-resources also takes care of exceptions thrown while closing ... but I am going off track. (Read a tutorial on try with resources for all of the details.)
Can I avoid this by simply terminating the function through a return?
No. Closeable resources are not closed simply by a return
.
The pointers are declared locally within the function, so I think they should be destroyed at the end of the function like any declared variable but being pointers they make use of reserved memory space, ...
This is incorrect in a number of respects:
new
expression.null
to the variable.)In short, what you think happens with Java local variables doesn't actually happen. Java is fundamentally different to C++ in this respect.
... so I don't know what happens with that pointer at the end of the function without closing it, I do not know if it is destroyed, closed or remains in memory inaccessible within the thread.
In fact, nothing happens to the heap object when a variable that holds a reference goes out of scope.
The heap object stays there until the garbage collector (eventually!) discovers that the object is no longer reachable. Then (and only then) will it delete the object.
For most objects this is not a problem.
For objects that hold handles for external resources that need to be released (e.g. file descriptors, memory-mapped files, etc) this is a problem. This is why these kinds of objects need to be managed more directly ... by an explicit close call, or using try with resources.
(Note that objects that hold handles for external resources will typically have a finalization mechanism of some kind that will close the resources. The problem is that it doesn't happen until after garbage collection ... and that may be too late.)