终结方法finalize()通常是不可预测的,也是很危险的,一般情况下是不必要的。

  • Java语言规范并不保证finalize()会被及时执行,即不确定终结方法执行时间,只规定在对象被垃圾回收之前执行
  • 不应该依赖终结方法来改变重要的持久状态
  • 终结方法会造成严重的性能损耗

正确使用终结方法

  1. 防止用户使用了创建了对象后,并未使对象提供的显式终止方法(如果有)。终结方法可以充当安全网。

  2. 本地对等体(是一个本地对象,普通对象通过本地方法委托给一个本地对象。)不是一个普通对象,垃圾回收器不会回收它。一般情况下,终结方法需要能够完成所有必要的工作释放资源,如果需要即时释放资源,那么就需要给本地对等体指定一个显式的终止方法。

终结方法链不会自动执行,如果类有终结方法,并且子类覆盖了终结方法,则子类的终结方法必须手工调用超类的终结方法。你应该在try块中终结子类,并在相应的finally块中调用超类的终结方法。

终结方法守卫者

如果子类实现者覆盖了超类的终结方法,但是忘了调用超类的终结方法,那么超类的终结方法永远不会调用。为了防止此种情况出现,可以使用终结方法守卫者。即为每个被终结的对象创建一个附加的对象,该附加对象为一个匿名类,将外围类的终结操作如释放资源放入该匿名类的终结方法中。同时,外围类保存着对该匿名类的唯一引用,即复制给私有变量域。

 class A {

     @SuppressWarnings("unused")
//终结守卫者
private final Object finalizerGuardian = new Object() { @Override
//终结守卫者的终结方法将被执行
protected void finalize() {
System.out.println("A finalize by the finalizerGuardian");
}
}; @Override
//由于终结方法被子类覆盖,该终结方法并不会被执行
protected void finalize() {
System.out.println("A finalize by the finalize method");
} public static void main(String[] args) throws Exception {
B b = new B();
b = null;
System.gc();
Thread.sleep(500);
}
} class B extends A { @Override
public void finalize() {
System.out.println("B finalize by the finalize method");
} }

输出:

A finalize by the finalizerGuardian
B finalize by the finalize method

Java终结方法的使用(终结守卫者)的更多相关文章

  1. Java 终结方法 避免使用终结方法

    在Java中,当一个对象变得不可到达时,垃圾回收器会回收与该对象相关联的存储空间.用try-finally块来回收其他的非内存资源. 终结方法的缺点在于不能保证会被及时地执行.从一个对象变得不可到达开 ...

  2. EffectiveJava(7)避免使用终结方法

    避免使用终结方法 1.使用终结方法会导致行为不稳定,性能降低,以及可移植性的问题.(终结线程的优先级过低) 终结方法不能保证被及时的执行(从一个对象变得不可到达开始,到中介方法被执行,所花费的时间是任 ...

  3. effective java —— 终结方法守卫者

    目录: effective java —— 终结方法守卫者 effective java 第2章:创建和销毁对象.第7条 : 避免使用终结方法.最后的“终结方法守卫者 (finalizer guard ...

  4. [转]Java远程方法调用

    Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远 ...

  5. Java:方法的参数是传值还是传引用

    Java中方法的参数总是采用传值的方式. 下列方法欲实现对象的交换,但实际上是不能实现的. public void swap(simpleClass a,simpleClass b){ simpleC ...

  6. Java之方法重载篇(我重载了,你要如何来调用我。。)

      一.课前引言 请看一下代码,你发现什么特殊之处了吗? public class MethodOverload { public static void main(String[] args) { ...

  7. Java parseInt()方法

    1.Java parseInt()方法 使用此方法得到的原始数据类型的一个特定的字符串. parseXxx()是一个静态方法,可以有一个参数或两个. java parseInt() 语法:   sta ...

  8. 几种任务调度的 Java 实现方法与比较

    综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,并对其优缺 ...

  9. JNI系列——C文件中的方法调用Java中方法

    1.创建xxx.jni包并在该包下实现一些Java的方法,和要调用的本地方法 2.实现MainActivity中的按钮点击事件-即点击按钮调用本地的方法 3.在C文件中的方法中回调Java的方法 3. ...

随机推荐

  1. 代码管理必备-----git使用上传码云

    作为一个程序员,你要学会代码的管理,这是一个最基本的修养,就像是一个剑客的剑谱,代码管理,目前流行的是svn和git,但是很不好的是git如果没有插件的话,很多人都不会用git bash 来实现自己的 ...

  2. h264多slice

    1, h264编码以macroblock为最小单位(简称MB),多个连续的MB组成一个slice,每个slice编码输出一个NALU 2, 划分slice的方式可以按照固定个数MB的方式: 也可以以对 ...

  3. java创建自定义类的数组

    今天在学图论的最小生成树,开始一直在想是用邻接矩阵还是关联矩阵来表示图,但是发现这样都会有好多空间浪费.于是我就自定义一个边的类,里面包含了权值,关联的端点1,端点2,和图的表示字母.发现我想创建11 ...

  4. Web前端开发学习笔记(二)

    Homework2:http://my.ss.sysu.edu.cn/wiki/display/WEB/Homework+2+-+Movie+Review 这份作业跟布局相关,因此很多都是布局的知识: ...

  5. SpringMVC国际化支持

    这周公司领导希望我对一个项目,出一个国际化的解决方案,研究两个小时,采用了SpringMVC的国际化支持,在此记录下. 原理: 在DispatchServlet中注册localeResolver(区域 ...

  6. PyTorch官方中文文档:自动求导机制

    自动求导机制 本说明将概述Autograd如何工作并记录操作.了解这些并不是绝对必要的,但我们建议您熟悉它,因为它将帮助您编写更高效,更简洁的程序,并可帮助您进行调试. 从后向中排除子图 每个变量都有 ...

  7. HTTP的长连接,你不知道的连接。。。

    长连接起源 什么样的连接才能称之为长连接?要多长.... http是一种无状态的协议,也就是stateless协议,而http协议又是建立在tcp/ip协议的基础之上的. 无状态表示每次请求都是一次独 ...

  8. [BZOJ2467] [中山市选2010] 生成树 (排列组合)

    Description 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角 ...

  9. 【noip模拟】最小点覆盖

    Time Limit: 1000ms      Memory Limit: 128MB Description 最小点覆盖是指在二分图中,用最小的点集覆盖所有的边.当然,一个二分图的最小点覆盖可能有很 ...

  10. pt工具主从一致性检查并修复以及版本3.0.4的版本缺点

    pt-table-checksum和pt-table-sync分别检验master-slave的数据不一致并修复. 1.本次测试环境 [root@172-16-3-190 we_ops_admin]# ...