6

Everything that I have read about the java finalize method says NOT to use it. It seems that it is almost never guaranteed to be called and may present problems even when it is.

There are a few other questions that ask when to use it, and it seems the general consensus is NEVER.

I have never used it myself (mainly because of the warnings not to), and I haven't seen it used anywhere.

Are there any cases at all where it would be appropriate? Are there cases where there is no alternative?

If not, why is it there? Are there internal classes that do use it and require the method to be available? Or is it just something that shouldn't be there?

I'm not so much interested in when I should use it (which has been answered with "never"), but clarification on why it is even there given that answer of "never". If it is so useless and dangerous, why hasn't it been depreciated and removed?

Matthew
  • 7,440
  • 1
  • 24
  • 49
  • http://stackoverflow.com/questions/158174/why-would-you-ever-implement-finalize – Alex - GlassEditor.com Feb 27 '16 at 07:21
  • @Alex My question is similar, but I don't think it is exactly the same. I'm not asking so much why I would use it (I shouldn't) as why it is there in the first place (given that I shouldn't). Do the java APIs require it for some reason? Does the JVM have to see that method on all objects for some reason? Or are there cases where there is simply no other alternative? (The third of those is addressed by the question you linked, but the first two are not). – Matthew Feb 27 '16 at 07:27
  • @Alex I edited my title to make this distinction a little clearer. – Matthew Feb 27 '16 at 07:34
  • Well, the [JLS](http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.6) requires it to be there, but the only reason given is _Finalizers provide a chance to free up resources that cannot be freed automatically by an automatic storage manager. In such situations, simply reclaiming the memory used by an object would not guarantee that the resources it held would be reclaimed._ The javadoc of finalize also says _the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded_. I don't know of another reason it was created. – Alex - GlassEditor.com Feb 27 '16 at 07:56

2 Answers2

3

Backwards compatibility. Someone first thought it would be a good idea, and then when the world realized it was not such a great idea, it was too late.

These things are barely ever removed. Java is full of concepts that are considered bad idea nowadays but haven't been removed nevertheless - some more examples that come to my mind are clone() or Thread.stop().

Community
  • 1
  • 1
Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • Was there a point that it was being recommended, or were the earlier garbage collectors more reliable in running it? It seems that it shouldn't have caught on giving the problems. And if it didn't catch on, it seems that it should be safer to remove it. I know that java likes to depreciate things and still not remove them. Is there any reason that it hasn't at least been depreciated? – Matthew Feb 27 '16 at 07:15
  • 1
    I don't think they used to be more reliable. Some dangers came to be known during time as people attempted to use it. Some more unreliability may come from today's JAva GCing less often (due to more memory and strategy of delaying GC as much as possible). – Jiri Tousek Feb 27 '16 at 07:26
  • 1
    My understanding is that `finally()` is mainly there to allow freeing resources that are not under GC's control *and* whose freeing is not critical (i.e. if JVM is shut down, they'll be freed automatically) - like allocating memory through some native code when working with non-Java components, DLLs etc. – Jiri Tousek Feb 27 '16 at 07:33
  • Ok, that comment is helpful. That is similar to what @MartinS answered, but the distinction on not-critical-to-free resources seems a better use. Using it to get rid of a resource whose memory I want back but isn't going to leave the system in some horrible state if the JVM shuts down seems a safer use of it. – Matthew Feb 27 '16 at 07:38
  • 1
    @Matthew The example I mention would also be considered non-critical resources by that matter. Even though the JVM does not control the memory, it will still be freed by the operating system if the JVM shuts down. It's just that you do not want a memory leak in long running programs :) – MartinS Feb 27 '16 at 07:42
2

One use-case where you might use it and where it would be acceptable is to free resources that are not under the control of the JVM i.e. that would not be freed otherwise. For example memory that has been allocated using sun.misc.Unsafe(*) has to be manually freed because it will not be garbage collected. So you could use the finalize method as a last resort to free the memory if it has not been freed before - just to make sure that your program does not have memory leaks. But these cases are rather rare and today Java provides better alternatives like the AutoClosable interface which has been introduce in Java 7.

You can find more examples in the OpenJDK source code, for example FileInputStream that uses the finalize method to make sure that it got closed.

(*) Don't use it, it's called Unsafe for a reason.

Edit: Answers for the questions from your comment

Do the java APIs require it for some reason?

Yes and no. The Java Language Specification states that it has to exist. Also some classes in the Java library use it (for example when they handle files) but no Java API requires you to implement it for your classes.

Does the JVM have to see that method on all objects for some reason?

Well yes again because the JLS says so and the garbage collector calls it for every object it collects.

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

But it does see the finalize method on all objects since Object implements it - and it does nothing per default.

protected void finalize() throws Throwable { }
MartinS
  • 2,759
  • 1
  • 15
  • 25
  • I can see why you would consider it in that case, but given that there is no guarantee that it will run, would it be something that you want to rely on to free those resources? I haven't really done anything like that, but it seems that there is still a good chance those resources will not be correctly freed given it's unpredictability. – Matthew Feb 27 '16 at 07:19
  • 1
    That's why I said "as a last resort". It is still better than doing nothing when a programmer forgot to free a resource somewhere, because you will at least have a good chance that `finalize` will be called eventually. – MartinS Feb 27 '16 at 07:21