终止

问: finalize()方法是用来做什么的?

答: finalize()方法可以被子类对象所覆盖,然后作为一个终结者,当GC被调用的时候完成最后的清理工作(例如释放系统资源之类)。这就是终止。默认的finalize()方法什么也不做,当被调用时直接返回。

对于任何一个对象,它的finalize()方法都不会被JVM执行两次。如果你想让一个对象能够被再次调用的话(例如,分配它的引用给一个静态变量),注意当这个对象已经被GC回收的时候,finalize()方法不会被调用第二次。

问: 有人说要避免使用finalize()方法,这是真的吗?

答: 通常来讲,你应该尽量避免使用finalize()。相对于其他JVM实现,终结器被调用的情况较少——可能是因为终结器线程的优先级别较低的原因。如果你依靠终结器来关闭文件或者其他系统资源,可能会将资源耗尽,当程序试图打开一个新的文件或者新的系统资源的时候可能会崩溃,就因为这个缓慢的终结器。

问: 应该使用什么来替代终结器?

答: 提供一个明确的用来销毁这个对象的方法(例如,java.io.FileInputStreamvoid close()方法),并且在代码中使用try - finally结构来调用这个方法,以确保无论有没有异常从try中抛出,都会销毁这个对象。参考下面释放锁的代码:

 Lock l = ...; // ... is a placeholder for the actual lock-acquisition code
l.lock();
try
{
// access the resource protected by this lock
}
finally
{
l.unlock();
}

这段代码保证了无论try是正常结束还是抛出异常都会释放锁。

问: 什么情况下适合使用终结器?

答: 终结器可以作为一个安全保障,以防止声明的终结方法(像是java.io.FileOutputStream对象的close()方法或者java.util.concurrent.Lock对象的Lock()方法)没有被调用。万一这种情况出现,终结器可以在最后被调用,释放临街资源。

问: 怎么写finalize()

答: 可以遵循下面这个模式写finalize()方法:

 @Override
protected void finalize() throws Throwable
{
try
{
// Finalize the subclass state.
// ...
}
finally
{
super.finalize();
}
}

子类终结器一般会通过调用父类的终结器来实现。当被调用时,先执行try模块,然后再在对应的finally中调用super.finalize();这就保证了无论try会不会抛出异常父类都会被销毁。

问: 如果finalize()抛出异常会怎样?

答: 当finalize()抛出异常的时候会被忽略。而且,对象的终结将在此停止,导致对象处在一种不确定的状态。如果另一个进程试图使用这个对象的话,将产生不确定的结果。通常抛出异常将会导致线程终止并产生一个提示信息,但是从finalize()中抛出异常就不会。

问: 我想实践一下finalize()方法,能提供一个范例吗?

答: 参考代码清单1.

 class LargeObject
{
byte[] memory = new byte[**]; @Override
protected void finalize() throws Exception
{
System.out.println("finalized");
}
} public class FinalizeDemo
{
public static void main(String[] args)
{
while (true)
new LargeObject();
}
}

代码清单1:实践finalize()

代码清单1中的代码写了一个FinalizeDemo程序,重复地对largeObject类实例化。每一个Largeobject对象将产生4M的数组。在这种情况下,由于没有指向该对象的引用,所以LargeObject对象将被GC回收。

GC会调用对象的finalize()方法来回收对象。LargeObject重载的finalize()方法被调用的时候会想标准输出流打印一条信息。它没有调用父类的finalize()方法,因为它的父类是Object,即父类的finalize()方法什么也不做。

编译(javac FinalizeDemo.java)并运行(java FinalizeDemo)代码清单1.当我在我的环境下(64位win7平台)使用JDK7u6来编译运行的时候,我看到一列finalized的信息。但是在JDK8的环境下时,在几行finalized之后抛出了java.lang.OutOfMemoryError

因为finalize()方法对于虚拟机来说不是轻量级的程序,所以不能保证你一定会在你的环境下观察到输出信息。

得到对象的类

问: gerClass()方法是用来做什么的?

答: 通过gerClass()方法可以得到一个和这个类有关的java.lang.Class对象。返回的Class对象是一个被static synchronized方法封装的代表这个类的对象;例如,static sychronized void foo(){}。这也是指向反射API。因为调用gerClass()的对象的类是在内存中的,保证了类型安全。

问: 还有其他方法得到Class对象吗?

答: 获取Class对象的方法有两种。可以使用类字面常量,它的名字和类型相同,后缀位.class;例如,Account.class。另外一种就是调用ClassfoeName()方法。类字面常量更加简洁,并且编译器强制类型安全;如果找不到指定的类编译就不会通过。通过forname()可以动态地通过指定包名载入任意类型地引用。但是,不能保证类型安全,可能会导致Runtime异常。

Java提高学习之Object(3)的更多相关文章

  1. Java提高学习之Object类详解(1)

    转自:http://www.importnew.com/10304.html 问:什么是Object类? 答:Object类存储在java.lang包中,是所有java类(Object类除外)的终极父 ...

  2. Java提高学习之Object(5)

    字符串形式的表现 Q1:toString() 方法实现了什么功能?A1:toString() 方法将根据调用它的对象返回其对象的字符串形式,通常用于debug. Q2:当 toString() 方法没 ...

  3. Java提高学习之Object(4)

    哈希码 问: hashCode()方法是用来做什么的? 答: hashCode()方法返回给调用者此对象的哈希码(其值由一个hash函数计算得来).这个方法通常用在基于hash的集合类中,像java. ...

  4. Java提高学习之Object(2)

    Equality 问:euqals()函数是用来做什么的? 答:equals()函数可以用来检查一个对象与调用这个equals()的这个对象是否相等. 问:为什么不用“==”运算符来判断两个对象是否相 ...

  5. java基础学习总结——Object类

    一.Object类介绍

  6. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  7. Java提高篇(三二)-----List总结

    前面LZ已经充分介绍了有关于List接口的大部分知识,如ArrayList.LinkedList.Vector.Stack,通过这几个知识点可以对List接口有了比较深的了解了.只有通过归纳总结的知识 ...

  8. java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  9. Java提高篇(三二)-----List总结

    前面LZ已经充分介绍了有关于List接口的大部分知识,如ArrayList.LinkedList.Vector.Stack,通过这几个知识点能够对List接口有了比較深的了解了.仅仅有通过归纳总结的知 ...

随机推荐

  1. JavaScript 面向对象思想 贪吃蛇游戏

    js代码: 游戏的对象 ,食物,蛇 ,游戏控制思路如下 (完整代码在https://github.com/774044859yf/ObjectSnakeGame下载) var snake = { aS ...

  2. BestCoder Round #75 1002 - King's Phone

    问题描述 阅兵式上,国王见到了很多新奇东西,包括一台安卓手机.他很快对手机的图形解锁产生了兴趣. 解锁界面是一个 3×33 \times 33×3 的正方形点阵,第一行的三个点标号 1,2,31, 2 ...

  3. [Linked List]Remove Nth Node From End of List

    Total Accepted: 84303 Total Submissions: 302714 Difficulty: Easy Given a linked list, remove the nth ...

  4. C++ buffer缓冲区的秘密

    在搞数据库和C++进行连接的时候,遇到一个问题,就是如果前面用到了fflush(stdin)即清空缓冲区,就OK,如果不清空缓冲区就不能把记录加入到Mysql的数据库中, 但是即便如此,这个问题目前还 ...

  5. C++ vector 实现二维数组时, 在类的头文件中定义时遇到"应输入类型符"的问题?

    见下,当我在类的声明文件中定义二维vector时,提示我应输入类型说明符; 但是相同的格式定义,在类中将二维vector修改为在源文件中定义就可以顺利通过,并顺利执行打印 打印结果如下: 望大神来解惑 ...

  6. 删除数组中等于某个key的所有元素

    题目描述: 给定一个数组和一个值,在原地删除与值相同的数字,返回新数组的长度. 这道题目做暴力的想法就是,用一个指针从头到尾遍历,删除哪个元素就把后面的元素统一向前移动一个位置.但是这样的时间复杂度很 ...

  7. VS2010 添加资源文件后,出现 “LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”错误

    1>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 解决方法: 一.1.点击“项目”-->“属性”-->“清单工具” 2.‘输入 ...

  8. C# 单向链表数据结构 (一)

    单向链表数据结构是有节点组成,每个节点包含两部分,第一部分为存储数据,第二部分为指向下一个节点的指针.注意,有两个特色的节点,分别为“头节点”和“尾节点”,头节点本身没有数据,只存储下一个节点的指针, ...

  9. 转: JavaScript函数式编程(二)

    转: JavaScript函数式编程(二) 作者: Stark伟 上一篇文章里我们提到了纯函数的概念,所谓的纯函数就是,对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环 ...

  10. 转自:Python函数式编程指南(二):函数

    2. 从函数开始 2.1. 定义一个函数 如下定义了一个求和函数: 1 2 def add(x, y):     return x + y 关于参数和返回值的语法细节可以参考其他文档,这里就略过了. ...