views:

487

answers:

7

I came across this question and am looking for some ideas?

+13  A: 

You do not need (nor should you try to use) destructors - or what they are called in Java: "Finalizers".

The VM specification does allow for VM implementations to never call them. So they are not reliable for resource releases and the like. Generally speaking the code in the finalize() method of any object can be called by the VM before the object is garbage collected, but as this is not mandatory, you should avoid it.

Daniel Schneller
`finalize()` is *not* a destructor, it has a different and quite specific meaning.
skaffman
You are right. I tried to make the point that there is a difference in the concept by explaining that it is NOT suitable for resource release and other cleanup tasks which is usually what a destructor would be used for.
Daniel Schneller
The only thing one should know about finalize is: Never ever use it, or baby Jesus will cry :-)!
Helper Method
You should use it but log when it is called if the resource you are closing is still open. That way you know you missed something can go fix it. Personally I don't do that either, I just make sure my code is correct :-)
TofuBeer
What is system.gc() ? Can we use that to request garbage collection ?
Phoenix
@TofuBeer. It should be noted that doing that will place a (significant?) extra burden on the garbage collector; it should be done sparingly, if at all. For more detail, read up on the alternative using `ReferenceQueue`, starting with the package documentation for java.lang.ref.
Software Monkey
System.gc makes a request to garbage collect. It may do nothing. If it does anything it may collect no garbage. If it collects garbage it may not collect all of the garbage.
TofuBeer
It is mandatory that the finalizer get called before the object is collected: http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6 "The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused."
TofuBeer
+4  A: 

Java is garbage-collected, so there is no way to tell when your destructor would be called (when your object will be garbage-collected).

There is a finalize (inherited) method but you can't rely on that for the exact reasons above (you can't predict when -and if- it will be called).

ChristopheD
+1  A: 

You can check this for more info on finalization - finalize() method

pnt
+1  A: 

If you just need to cleanup some resources, you can call Runtime.getRuntime().addShutdownHook

Pierre
A: 

http://java.sun.com/docs/books/tutorial/java/index.html

msw
-1 Should have better read that by yourself.
Helper Method
+1  A: 

Automatic object "destruction" in Java never happens at a guaranteed time. The only grantees for garbage collection are that before an object is collected the finalizer method will be called. Of course the garbage collector is never guaranteed to run, or do anything when it does run. So there is no guarantee that the finalize method will be called.

If you want to simulate C++ destructors in Java the best way is to use the following idiom (there are variations when it comest to exception handling - I'll just show the simplest case here):

final Resource r;

r = new Resource();

try
{
    r.use();
}
finally
{
    r.cleanup();
}

where the "cleanup" method is the "destructor".

This is more like the C++ Resource Acquisition Is Initialization idiom which is really for stack based objects, but isn't as nice.

TofuBeer
Others have said there is no guarantee that finalize() will be called. If I understand you correctly, you're saying that finalize WILL be called IF the object is destroyed by the garbage collector. So the only reason finalize() wouldn't be called is because the garbage collector didn't happen to destroy that particular object?
MatrixFrog
Yes, if the object is going to be collected then the finalizer will be called. There is no grantee that the object is every collected though, so no guarantee that the finalizer is ever called. Look at http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6 - "The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused."
TofuBeer
A: 

Since others are talking about normal cases.. There are special cases where you want to create destroy(), destruct(), releaseExternalResources(), shutdown() etc. methods that should be actively called by the entity that controls the life cycle of that instance.

For example, an object can be an ActiveObject, which has live threads in it. In this case, you want to shut them down because else you will have memory leaks.

While one may not call that a destructor...

On a sidenote, I guess that interview question was intended as a trick question!

Enno Shioji