第7条:避免使用终结方法

终结方法(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实例相关联的资源,但是该实例仍然处于可用的状态,如果有必要的话,会重新分配资源。




总结:除非作为安全网,或者是为了终止非关键的本地资源,否则请不要使用终结方法。在这些很少见的情况下,既然使用了终结方法,就要记住调用super.finalize。如果用终结方法作为安全网,要记得记录终结方法的非法用法。最后,如果需要吧终结方法与公有的非final类关联起来,请考虑使用终结方法守护者,以确保即使子类的终结方法未能调用super.finalize,该终结方法也会被执行。


  1. @Override  
  2. protected void finalize() throws Throwable {  
  3.     try{  
  4.         ...//Finalize subclass state  
  5.     } finally {  
  6.         super.finalize();  
  7.     }  
  8. }  

demo:


  1. class A {    
  2.     B b;    
  3.     
  4.     public A(B b) {    
  5.         this.b = b;    
  6.     }    
  7.     
  8.     @Override    
  9.     public void finalize() {    
  10.         System.out.println("A finalize");    
  11.         C.a = this;    
  12.     }    
  13. }   
  14.   
  15. class B {    
  16.     String name;    
  17.     int age;    
  18.     
  19.     public B(String name, int age) {    
  20.         this.name = name;    
  21.         this.age = age;    
  22.     }    
  23.     
  24.     @Override    
  25.     public void finalize() {    
  26.         System.out.println("B finalize");    
  27.     }    
  28.     
  29.     @Override    
  30.     public String toString() {    
  31.         return name + " is " + age;    
  32.     }    
  33. }    
  34.   
  35.   
  36. class C {    
  37.     static A a;    
  38. }   
  39.   
  40. public class Main {    
  41.     public static void main(String[] args) throws Exception {    
  42.         A a = new A(new B("allen"20));    
  43.         a = null;    
  44.     
  45.         System.gc();    
  46.         Thread.sleep(5000);    
  47.         System.out.println(C.a.b);    
  48.     }    
  49. }    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值