Java提高学习之Object(3)
终止
问: finalize()
方法是用来做什么的?
答: finalize()
方法可以被子类对象所覆盖,然后作为一个终结者,当GC被调用的时候完成最后的清理工作(例如释放系统资源之类)。这就是终止。默认的finalize()
方法什么也不做,当被调用时直接返回。
对于任何一个对象,它的
finalize()
方法都不会被JVM执行两次。如果你想让一个对象能够被再次调用的话(例如,分配它的引用给一个静态变量),注意当这个对象已经被GC回收的时候,finalize()
方法不会被调用第二次。
问: 有人说要避免使用finalize()
方法,这是真的吗?
答: 通常来讲,你应该尽量避免使用finalize()
。相对于其他JVM实现,终结器被调用的情况较少——可能是因为终结器线程的优先级别较低的原因。如果你依靠终结器来关闭文件或者其他系统资源,可能会将资源耗尽,当程序试图打开一个新的文件或者新的系统资源的时候可能会崩溃,就因为这个缓慢的终结器。
问: 应该使用什么来替代终结器?
答: 提供一个明确的用来销毁这个对象的方法(例如,java.io.FileInputStream
的void 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
。另外一种就是调用Class
的foeName()
方法。类字面常量更加简洁,并且编译器强制类型安全;如果找不到指定的类编译就不会通过。通过forname()
可以动态地通过指定包名载入任意类型地引用。但是,不能保证类型安全,可能会导致Runtime
异常。
Java提高学习之Object(3)的更多相关文章
- Java提高学习之Object类详解(1)
转自:http://www.importnew.com/10304.html 问:什么是Object类? 答:Object类存储在java.lang包中,是所有java类(Object类除外)的终极父 ...
- Java提高学习之Object(5)
字符串形式的表现 Q1:toString() 方法实现了什么功能?A1:toString() 方法将根据调用它的对象返回其对象的字符串形式,通常用于debug. Q2:当 toString() 方法没 ...
- Java提高学习之Object(4)
哈希码 问: hashCode()方法是用来做什么的? 答: hashCode()方法返回给调用者此对象的哈希码(其值由一个hash函数计算得来).这个方法通常用在基于hash的集合类中,像java. ...
- Java提高学习之Object(2)
Equality 问:euqals()函数是用来做什么的? 答:equals()函数可以用来检查一个对象与调用这个equals()的这个对象是否相等. 问:为什么不用“==”运算符来判断两个对象是否相 ...
- java基础学习总结——Object类
一.Object类介绍
- 转载-java基础学习汇总
共2页: 1 2 下一页 Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3 Java基础学习总结——Java对象的序列化和 ...
- Java提高篇(三二)-----List总结
前面LZ已经充分介绍了有关于List接口的大部分知识,如ArrayList.LinkedList.Vector.Stack,通过这几个知识点可以对List接口有了比较深的了解了.只有通过归纳总结的知识 ...
- java提高篇(四)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- Java提高篇(三二)-----List总结
前面LZ已经充分介绍了有关于List接口的大部分知识,如ArrayList.LinkedList.Vector.Stack,通过这几个知识点能够对List接口有了比較深的了解了.仅仅有通过归纳总结的知 ...
随机推荐
- SQL语言学习-数据定义语言
Sql语言至今已经有6个版本.SQL查询语言包括了所有对数据的操作命令,这些操作可分为四类:数据定义语言(DDL).数据操纵语言(DML).数据控制语言(DCL)和嵌入式SQL语言. 数据定义语言(D ...
- iOS 键盘弹出遮挡输入框
#pragma mark 键盘弹出遮挡输入框 //开始编辑输入框的时候,软键盘出现,执行此事件 -(void)textFieldDidBeginEditing:(UITextField *)textF ...
- python基础之语句结束
1 2 3 4 5 if a : if b: # 这里是if b的作用区间 #这里是if a的作用区间 #这里不在if 区间 python 是按缩进来识别代码块的.
- Mysql源码安装
首先去http://dev.mysql.com/downloads/mysql/5.6.html 下载mysql的源代码,记住是source code,别下别的版本 1.安装依赖的包 yum -y i ...
- mysql 批量更新
bs_user 表,我们叫他 bu表, 字段user_id,len_id, think_wellUser 表,我们简称为tw表,中的user_id ,len_id 其中tw表的user_id 是bu表 ...
- c#访问各数据库的providerName各驱动
在machine.config(C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/CONFIG)文件中有这么一段: <system.data> & ...
- PSR-2 Coding Style Guide
本文主要是对PSR-2 的简单翻译. 英文源址 http://www.php-fig.org/psr/psr-2/ PSR2继承和扩展PSR1--基本编码规范 本手册的目的是使用一系列共同遵守的编码格 ...
- mysql 查询重复的(不区分大小写)数据的SQL优化
在mysql中查询不区分大小写重复的数据,往往会用到子查询,并在子查询中使用upper函数来将条件转化为大写.如: select * from staticcatalogue WHERE UPPER( ...
- hdu 5442 Favorite Donut 最大表示法+kmp
题目链接 给你一个字符串, 然后把他想象成一个环. 从某一个地方断开,然后逆时针或顺时针, 都可以形成一个字符串, 求字典序最大的那种. 输出断开位置以及是顺时针还是逆时针. 如果两个一样, 输出位置 ...
- tornado web框架
tornado web框架 tornado简介 1.tornado概述 Tornado就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本.Tornado 和现在的主流 Web ...