避免使用终结
来源:互联网 发布:万物生长齐溪好丑 知乎 编辑:程序博客网 时间:2024/05/02 04:34
终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的。
如果程序依赖于终结方法被执行的时间点,那么这个程序的行为在不同的JVM实现中会大相径庭。Java语言规范不仅不保证终结方法会被及时的执行,而且根本不保证他们会被执行。不应该依赖终结方法来更新重要的持久状态。
不要被System.gc和System.runFinalization这两个方法所诱惑,他们确实增加了终结方法被执行的机会,但是他们不保证终结方法一定被执行。唯一声称保证终结方法被执行的方法是System.runFinalizersOnExit,以及他臭名昭著的孪生兄弟Runtime.runFinalizersOnExit。这两个方法都有致命的缺陷,都被废弃了。使用终结方法有一个非常严重的(Severe)性能损失。提供一个显示终止的方法来终止一些必要的资源。
显示终止方法的典型例子是InputStream、OutputStream和java.sql.Connection上的close方法。
另一个例子是java.util.Timer上的cancel方法,它执行必要的状态改变,使得与Timer实例相关联的该线程温和的终止自己。
java.awt中的例子还包括Graphics.dispose和Window.dispose。
Image.flush,他会释放所有与Image实例相关联的资源,但是该实例仍然处于可用的状态,如果有必要的话,会重新分配资源。
如果程序依赖于终结方法被执行的时间点,那么这个程序的行为在不同的JVM实现中会大相径庭。Java语言规范不仅不保证终结方法会被及时的执行,而且根本不保证他们会被执行。不应该依赖终结方法来更新重要的持久状态。
不要被System.gc和System.runFinalization这两个方法所诱惑,他们确实增加了终结方法被执行的机会,但是他们不保证终结方法一定被执行。唯一声称保证终结方法被执行的方法是System.runFinalizersOnExit,以及他臭名昭著的孪生兄弟Runtime.runFinalizersOnExit。这两个方法都有致命的缺陷,都被废弃了。使用终结方法有一个非常严重的(Severe)性能损失。提供一个显示终止的方法来终止一些必要的资源。
显示终止方法的典型例子是InputStream、OutputStream和java.sql.Connection上的close方法。
另一个例子是java.util.Timer上的cancel方法,它执行必要的状态改变,使得与Timer实例相关联的该线程温和的终止自己。
java.awt中的例子还包括Graphics.dispose和Window.dispose。
Image.flush,他会释放所有与Image实例相关联的资源,但是该实例仍然处于可用的状态,如果有必要的话,会重新分配资源。
总结:
除非作为安全网,或者是为了终止非关键的本地资源,否则请不要使用终结方法。在这些很少见的情况下,既然使用了终结方法,就要记住调用super.finalize。如果用终结方法作为安全网,要记得记录终结方法的非法用法。最后,如果需要吧终结方法与公有的非final类关联起来,请考虑使用终结方法守护者,以确保即使子类的终结方法未能调用super.finalize,该终结方法也会被执行。
@Override protected void finalize() throws Throwable { try{ ...//Finalize subclass state } finally { super.finalize(); } }
demo:
class A { B b; public A(B b) { this.b = b; } @Override public void finalize() { System.out.println("A finalize"); C.a = this; } } class B { String name; int age; public B(String name, int age) { this.name = name; this.age = age; } @Override public void finalize() { System.out.println("B finalize"); } @Override public String toString() { return name + " is " + age; } } class C { static A a; } public class Main { public static void main(String[] args) throws Exception { A a = new A(new B("allen", 20)); a = null; System.gc(); Thread.sleep(5000); System.out.println(C.a.b); } }
0 0
- 避免使用终结函数
- 避免使用终结
- 避免使用终结方法。
- 避免使用终结方法
- 07、避免使用终结方法
- 7、避免使用终结方法
- 07-避免使用终结方法
- 第7条:避免使用终结方法
- 第6条:避免使用终结函数
- 第7条:避免使用终结方法
- Effective Java (7) 避免使用终结方法
- Effective Java (7) - 避免使用终结方法
- 第7条:避免使用终结方法
- 第七条 避免使用终结方法
- EffectiveJava(7)避免使用终结方法
- 第7条:避免使用终结方法
- 高效Java07:避免使用终结方法(finalizer)
- Effective Java -- 避免使用终结方法
- 第十四章 数据库查询事例 上机1.2.3
- 【Unity插件】FingerGestures 插件使用
- N-gram
- 蓝桥杯 邮局
- Eclipse导入源码
- 避免使用终结
- 函数局部变量的返回
- 算法概论 - 8.8
- 计算机学习第四阶段面向实战
- Spring 之AOP AspectJ切入点语法详解(最全面、最详细。)
- Android入门开发之FlameLayout(九)
- 数组引用:C++ 数组做参数 深入分析
- iOS审核这些坑,腾讯游戏也踩过
- 坚持#第109天~不耽误做的这一件事就行!