package com.example.foo;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
/**
* Demonstration of failing finalize-implementations. Just run main, wait and see that it does not
* actually print any messages other than "good bye!", even though there are 5
* System.out.println(...) in the finalize-methods.
*
*
* However, finalize is run even if the instance was not created properly (Exception in * constructor). This may lead to problems, as the resources to close might not even exist. * *
* This answers this question: "Why is there no guarantee that {@link Object#finalize()} is run?" * *
* If you want an answer to the question: "Then what can I do to properly use finalize()?"
* The answer is: Don't!
* Not just because of the problems presented here. There are actually more problems!
* Here's a better alternative: http://claude-martin.ch/java-cleanup/
*/
public class SomeClass {
/**
* Finalize of Object is not invoked by some JVMs because it is known to be empty. This is
* relevant if you thought you could use a tools that can intercept invocation of finalize (as in
* aspect-oriented programming).
*/
static final class Finalize1 {
// no finalize
}
/** Class and method not final. */
static class Finalize2 {
@Override
protected void finalize() throws Throwable {
// not final -> extending class doesn't have to call this method.
System.out.println("Finalize2");
}
}
/**
* Finalize allocates new data and fails. GC runs it but you have no guarantee that the JVM can
* run it successfully.
*/
static final class Finalize3 {
@Override
protected void finalize() throws Throwable, OutOfMemoryError {
// What if memory is already running out?
// Chances are high - why else would gc be running?
// Then even a small array could fail:
byte[] bytes = new byte[Integer.MAX_VALUE];
// OutOfMemoryError was thrown!
System.out.println("Finalize3 " + bytes[0]);
// Also not run:
super.finalize();
}
}
static Finalize4 finalize4;
/**
* This is just to show that you, as the author of a class, can not prevent that an instance is
* referenced from a static field. This is also true for all data structures that exist until the
* JVM exits.
*/
static final class Finalize4 {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize4");
}
}
/**
* JVM could end abruptly. Again, you have no control over this when you write a class.
*/
static final class Finalize5 {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize5");
}
}
/** Runs Garbage Collection. */
static void gc(int n) {
final List