用 AutoCloseable 替代终结机制,仅将 Cleaner 用作防御性后备方案。
代码对比
✕ Finalization
@Override
protected void finalize() throws Throwable {
nativeHandle.release();
}
✓ Java 9+
final class NativeResource implements AutoCloseable {
private static final Cleaner CLEANER = Cleaner.create();
private static final class State implements Runnable {
private final long handle;
State(long handle) {
this.handle = handle;
}
@Override
public void run() {
release(handle);
}
}
private final Cleaner.Cleanable cleanable;
NativeResource(long handle) {
cleanable = CLEANER.register(this, new State(handle));
}
@Override
public void close() {
cleanable.clean();
}
}
发现此代码有问题? 告诉我们。
为什么现代方式更好
确定性
Try-with-resources 会在已知时机释放资源。
生命周期更安全
避免终结器复活和不可预测的执行顺序。
防御性后备方案
Cleaner 无需重写 finalize() 即可回收泄漏的资源。
旧方式
重写 finalize()
现代方式
AutoCloseable 和 Cleaner
自 JDK
9
难度
高级
JDK 支持
从终结器迁移到确定性资源清理
可用
Cleaner 和终结机制弃用自 JDK 9 起可用(2017 年 9 月)
工作原理
终结机制已被弃用并计划移除,既不能及时清理,也无法保证可靠的执行顺序。实现 AutoCloseable,使调用者可通过 try-with-resources 在确定的时机释放资源。对于泄漏的资源,Cleaner 可作为最后手段调用同一个幂等清理操作;该操作不得持有已注册对象。
相关文档
证明