考虑以下代码:
final class FinalizerTest {
private static volatile FinalizerTest sharedInstance;
private FinalizerTest() {
this(throwNew());
}
private FinalizerTest(final String ignored) {
}
private static String throwNew() {
throw new UnsupportedOperationException();
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalize()'d from " + Thread.currentThread().getName());
sharedInstance = this;
}
public static void main(final String args[]) {
for (int i = 0; i < 10; i++) {
try {
new FinalizerTest();
} catch (final UnsupportedOperationException ignored) {
}
}
for (int i = 0; i < 20; i++) {
System.gc();
}
System.out.println(sharedInstance);
}
}
当无参数构造函数尝试为另一个构造函数求值时,抛出异常,因此对象初始化异常完成。
我观察到,在Java 1.5及更低版本中,终结器被调用(这允许未初始化的实例泄漏),而在Java 1.6以后,则不这样做(由于我测试了大对象和小堆)。
JVM 是否为未初始化的对象调用终结器?
您能指出我 JLS 中的相应变化吗?