import java.lang.ref.*;
class TestPhantomReference
{
public static void main(String[] args)throws Exception
{
String str = new String("hello,world");
//创建一个引用队列
ReferenceQueue rq = new ReferenceQueue();
//创建一个虚1引用,让这个引用引用到“hello,world”
PhantomReference pr = new PhantomReference(str,rq);
str = null;//切断str的强引用
System.out.println(pr.get());//取出虚引用所引用对象,但不能通过虚引用访问被引用对象,此处输出null
System.gc();
System.runFinalization();
//取出引用队列中最先进入队列的引用与pr比较
System.out.println(rq.poll() == pr);
}
}
import java.lang.ref.*;
class TestReference
{
public static void main(String[] args) throws Exception{
String str = new String("Hello world");//注意:此处不能使用//str = "Hello world";因为这样赋值时,系统会缓存//这个字符串(会使用强引用引用他),系统不会回收被缓存的字符串WeakReference wr = new WeakReference(str);//将弱引用,引用到strstr = null;//切断str的强引用//去除若引用所引用的对象System.out.println(wr.get());//输出hello worldSystem.g();//强制垃圾回收
System.runFinalization();//再次取出弱引用所引用的对象
System.out.println( wr.get() );//输出null
}
}
由于垃圾回收的不确定性,当程序希望从若引用中取出被引用对象时,可能这个被引用对象已经被释放了。如果程序需要使用哪个被引用的对象,则必须重新创建该对象
这个过程可采用以下两种风格的代码完成
//取出虚引用所引用的对象
obj = wr.get();
//如果取出的对象为null
if(obj == null){
//重新创建一个新的对象,再次使用虚引用引用该对象
wr = new WeakReference(recreateIt());//obj = recreateIt();//recreateIt()是一个伪代码,用于创建生成一个obj对像//取出所引用的对象,将其赋给obj变量
obj = wr.get();//wr = new WeakReference(obj);
...//操作obj对象,
//切断obj对象之间的联系
obj = null;
}
对于未被注释的代码。由于垃圾回收的不确定性,可能在执行完if语句后,obj依然为空,所以这段代码不太好。但是当把他们换成注释里的代码时则不存在这个问题代码如下:
obj = recreateIt();
wr = new WeakReference(obj);