finalize()之后可以调用其他方法吗?
Can other methods be called after finalize()?
如果我有
public class Foo {
private boolean finalized = false;
public void foo() {
if (finalized)
throw new IllegalStateException("finalize() has been called.");
}
@Override public void finalize() {
super.finalize();
finalized = true;
}
}
是否可以保证,即使面对多线程,假设只有 GC 会调用 finalize()
,IllegalStateException
永远不会被抛出?
我知道在遇到导致对象不可垃圾回收的finalize()
方法时,该对象不会被垃圾回收,可能会调用其他方法。但是这个 finalize()
不会那样做。在finalize()
之后是否还有可能调用foo()
?
一个 不同的 对象完全有可能同时完成对 Foo
实例的引用 - 并且可能会复活 Foo
对象,允许它在完成后使用。这有点粗鲁,但肯定会发生。
即使没有复活,另一个终结器也可以从 its 终结器调用 Foo.foo()
:
public class Bar {
private final Foo foo;
@Override protected void finalize() {
// The finalizer in foo may already have executed...
foo.foo();
}
}
正如 Jon Skeet 所提到的,完全有可能在一个线程当前处于完成过程中时调用方法。
为了防止这种情况,您当然可以使代码线程安全。
public class Foo {
private boolean finalized = false;
public void foo() {
synchronized (this)
{
if (finalized)
throw new IllegalStateException("finalize() has been called.");
}
}
@Override public void finalize() {
synchronized (this)
{
super.finalize();
finalized = true;
}
}
}
注意:为了格外小心,我会将对 super.finalize() 的调用放在 try/finally 块中:
@Override public void finalize() {
synchronized (this)
{
try
{
super.finalize();
}
finally
{
finalized = true;
}
}
}
如果我有
public class Foo {
private boolean finalized = false;
public void foo() {
if (finalized)
throw new IllegalStateException("finalize() has been called.");
}
@Override public void finalize() {
super.finalize();
finalized = true;
}
}
是否可以保证,即使面对多线程,假设只有 GC 会调用 finalize()
,IllegalStateException
永远不会被抛出?
我知道在遇到导致对象不可垃圾回收的finalize()
方法时,该对象不会被垃圾回收,可能会调用其他方法。但是这个 finalize()
不会那样做。在finalize()
之后是否还有可能调用foo()
?
一个 不同的 对象完全有可能同时完成对 Foo
实例的引用 - 并且可能会复活 Foo
对象,允许它在完成后使用。这有点粗鲁,但肯定会发生。
即使没有复活,另一个终结器也可以从 its 终结器调用 Foo.foo()
:
public class Bar {
private final Foo foo;
@Override protected void finalize() {
// The finalizer in foo may already have executed...
foo.foo();
}
}
正如 Jon Skeet 所提到的,完全有可能在一个线程当前处于完成过程中时调用方法。
为了防止这种情况,您当然可以使代码线程安全。
public class Foo {
private boolean finalized = false;
public void foo() {
synchronized (this)
{
if (finalized)
throw new IllegalStateException("finalize() has been called.");
}
}
@Override public void finalize() {
synchronized (this)
{
super.finalize();
finalized = true;
}
}
}
注意:为了格外小心,我会将对 super.finalize() 的调用放在 try/finally 块中:
@Override public void finalize() {
synchronized (this)
{
try
{
super.finalize();
}
finally
{
finalized = true;
}
}
}