ad_qqread_mid_big">
用途和风格
这些类背后的原理就是避免在应用程序执行期间将对象留在内存中。相反,您以软引用、弱引用或虚引用的方式引用对象,这样垃圾收集器就能够随意地释放对象。当您希望尽可能减小应用程序在其生命周期中使用的堆内存大小时,这种用途就很有好处。您必须记住,要使用这些类,您就不能保留对对象的强引用。如果您这么做了,那就会浪费这些类所提供的任何好处。
另外,您必须使用正确的编程风格以检查收集器在使用对象之前是否已经回收了它,如果已经回收了,您首先必须重新创建该对象。这个过程可以用不同的编程风格来完成。选择错误的风格会导致出问题。请考虑清单 3 中从 weakreference 检索被引用对象的代码风格:
清单 3. 检索被引用对象的风格
obj = wr.get(); if (obj == null) { wr = new weakreference(recreateit()); //1 obj = wr.get(); //2 } //code that works with obj
|
研究了这段代码之后,请看看清单 4 中从 weakreference 检索被引用对象的另一种代码风格:
清单 4. 检索被引用对象的另一种风格
obj = wr.get(); if (obj == null) { obj = recreateit(); //1 wr = new weakreference(obj); //2 } //code that works with obj
|
请比较这两种风格,看看您能否确定哪种风格一定可行,哪一种不一定可行。清单 3 中体现出的风格不一定在所有情况下都可行,但清单 4 的风格就可以。清单 3 中的风格不够好的原因在于,if 块的主体结束之后 obj 不一定是非空值。请考虑一下,如果垃圾收集器在清单 3 的行 //1 之后但在行 //2 执行之前运行会怎样。recreateit() 方法将重新创建该对象,但它会被 weakreference 引用,而不是强引用。因此,如果收集器在行 //2 在重新创建的对象上施加一个强引用之前运行,对象就会丢失,wr.get() 则返回 null。
清单 4 不会出现这种问题,因为行 //1 重新创建了对象并为其指定了一个强引用。因此,如果垃圾收集器在该行之后(但在行 //2 之前)运行,该对象就不会被回收。然后,行 //2 将创建对 obj 的 weakreference。在使用这个 if 块之后的 obj 之后,您应该将 obj 设置为 null,从而让垃圾收集器能够回收这个对象以充分利用弱引用。清单 5 显示了一个完整的程序,它将展示刚才我们描述的风格之间的差异。(要运行该程序,其运行目录中必须有一个“temp.fil”文件。
清单 5. 展示正确的和不正确的编程风格的完整程序。
import java.io.*; import java.lang.ref.*;
class referenceidiom { public static void main(string args[]) throws filenotfoundexception { broken(); correct(); }
public static filereader recreateit() throws filenotfoundexception { return new filereader("temp.fil"); }
public static void broken() throws filenotfoundexception { system.out.println("executing method broken"); filereader obj = recreateit(); weakreference wr = new weakreference(obj);
system.out.println("wr refers to object " + wr.get());
system.out.println("now, clear the reference and run gc"); //clear the strong reference, then run gc to collect obj. obj = null; system.gc();
system.out.println("wr refers to object " + wr.get());
//now see if obj was collected and recreate it if it was. obj = (filereader)wr.get(); if (obj == null) { system.out.println("now, recreate the object and wrap it in a weakreference"); wr = new weakreference(recreateit()); system.gc(); //filereader object is not pinned...there is no //strong reference to it. therefore, the next //line can return null. obj = (filereader)wr.get(); } system.out.println("wr refers to object " + wr.get()); }
public static void correct() throws filenotfoundexception { system.out.println(""); system.out.println("executing method correct"); filereader obj = recreateit(); weakreference wr = new weakreference(obj);
system.out.println("wr refers to object " + wr.get());
system.out.println("now, clear the reference and run gc"); //clear the strong reference, then run gc to collect obj obj = null; system.gc();
system.out.println("wr refers to object " + wr.get());
//now see if obj was collected and recreate it if it was. obj = (filereader)wr.get(); if (obj == null) { system.out.println("now, recreate the object and wrap it in a weakreference"); obj = recreateit(); system.gc(); //filereader is pinned, this will not affect //anything. wr = new weakreference(obj); } system.out.println("wr refers to object " + wr.get()); } }
|
总结
如果使用得当,引用类还是很有用的。然而,由于它们所依赖的垃圾收集器行为有时候无法预知,所以其实用性就会受到影响。能否有效地使用它们还取决于是否应用了正确的编程风格;关键在于您要理解这些类是如何实现的以及如何对它们进行编程。
| >>>更多专题请看java的类专题 |
| 【收藏此页】【大 中 小】【打印】【关闭】 | 上一篇:java学习笔记 线程实例:一个钟表的实现 下一篇:jbuilder 2005单元测试之慨述
10万个软件免费高速下载 | | 教育教学 | 安全相关 | 游戏娱乐 | 源码下载 | 编程开发 | 数码软件 | 其它类别 | | 网络软件 | 联络聊天 | 系统工具 | 媒体工具 | 图形图像 | 应用软件 | 行业软件 | | | | | | | | | 相关文章 | ·nero 6高级使用图解 ·抠图―背景橡皮擦工具的使用 ·eclips使用秘技(绝对经典) ·电脑使用常见问题解答 ·copy命令使用说明 ·享受急速:四大主流网游加速器使用对 ·ocr软件使用宝典 ·高速下载+在线观看 风播bt使用教程 ·ie使用技巧大全――基本技巧篇 ·subversion 使用手记 | | | | 最新链接 | ·接口和抽象类的定义方式举例说明 ·用maven制作java项目发行包 ·java 基础入门 pom.xml 元素描述 ·用jbuilder2007开发扩展jsf标签的插 ·抽象类对象类和对象包装类 ·使用java实现在文件中添加字符串 ·instanceof和回调概念 ·java变量的赋值与传递 ·java se6调用java编译器的两种新方法 ·weblogic运用db的java控件访问数据库 | |
扫描关注微信公众号
|