Reference是java中的特殊引用类。描述的是特殊作用(主要是关于垃圾回收对象)的引用。
它有3个子类:
1.SoftReference;
2.WeakReference
3.PhantomReference
先看thinking in java 中的实例
package containers; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.LinkedList; //对引用的 描述与封装,Reference类 class VeryBig2{ private static final int SIZE= 10000; private long[] la= new long[SIZE]; private String ident; public VeryBig2(String id){ ident= id; } @Override public String toString() { return ident; } protected void finalize(){ System.out.println("Finalizing "+ ident); } } public class ReferencesTest { private static ReferenceQueue<VeryBig2> rq= new ReferenceQueue<VeryBig2>(); public static void checkQueue(){ Reference<? extends VeryBig2> inq= rq.poll(); if (inq != null) { System.out.println("In queue: "+ inq.get()); } } public static void main(String[] args) { int size= 10; if (args.length> 0) { size= new Integer(args[0]); } LinkedList<SoftReference<VeryBig2>> sa= new LinkedList<SoftReference<VeryBig2>>(); for (int i = 0; i < size; i++) { sa.add(new SoftReference<VeryBig2>(new VeryBig2("Soft "+ i), rq)); System.out.println("Just created: "+ sa.getLast()); checkQueue(); } LinkedList<WeakReference<VeryBig2>> wa= new LinkedList<WeakReference<VeryBig2>>(); for (int i = 0; i < size; i++) { wa.add(new WeakReference<VeryBig2>(new VeryBig2("Weak "+ i), rq)); System.out.println("Just created: "+ wa.getLast()); checkQueue(); } SoftReference<VeryBig2> s= new SoftReference<VeryBig2>(new VeryBig2("Soft")); WeakReference<VeryBig2> w= new WeakReference<VeryBig2>(new VeryBig2("Weak")); System.gc();//对无引用的对象,执行垃圾回收操作。并且,调用回收对象的finalize方法 LinkedList<PhantomReference<VeryBig2>> pa= new LinkedList<PhantomReference<VeryBig2>>(); for (int i = 0; i < size; i++) { pa.add(new PhantomReference<VeryBig2>(new VeryBig2("Phantom "+ i), rq)); System.out.println("Just created: "+ pa.getLast()); checkQueue(); } } }
output:
Just created: java.lang.ref.SoftReference@2a9931f5
Just created: java.lang.ref.SoftReference@2f9ee1ac
Just created: java.lang.ref.SoftReference@67f1fba0
Just created: java.lang.ref.SoftReference@3fbefab0
Just created: java.lang.ref.SoftReference@133c5982
Just created: java.lang.ref.SoftReference@5f186fab
Just created: java.lang.ref.SoftReference@3d4b7453
Just created: java.lang.ref.SoftReference@24c21495
Just created: java.lang.ref.SoftReference@41d5550d
Just created: java.lang.ref.SoftReference@1cc2ea3f
Just created: java.lang.ref.WeakReference@40a0dcd9
Just created: java.lang.ref.WeakReference@1034bb5
Just created: java.lang.ref.WeakReference@7f5f5897
Just created: java.lang.ref.WeakReference@4cb162d5
Just created: java.lang.ref.WeakReference@11cfb549
Just created: java.lang.ref.WeakReference@5b86d4c1
Just created: java.lang.ref.WeakReference@70f9f9d8
Just created: java.lang.ref.WeakReference@2b820dda
Just created: java.lang.ref.WeakReference@675b7986
Just created: java.lang.ref.WeakReference@2687816d
Just created: java.lang.ref.PhantomReference@7b11a3ac
In queue: null
Just created: java.lang.ref.PhantomReference@7ca83b8a
In queue: null
Finalizing Weak
Just created: java.lang.ref.PhantomReference@8dd20f6
In queue: null
Just created: java.lang.ref.PhantomReference@6d9efb05
In queue: null
Just created: java.lang.ref.PhantomReference@60723d7c
In queue: null
Just created: java.lang.ref.PhantomReference@6c22c95b
In queue: null
Just created: java.lang.ref.PhantomReference@5fd1acd3
In queue: null
Just created: java.lang.ref.PhantomReference@3ea981ca
In queue: null
Finalizing Weak 9
Just created: java.lang.ref.PhantomReference@6a8814e9
In queue: null
Finalizing Weak 8
Finalizing Weak 7
Just created: java.lang.ref.PhantomReference@c1503a3
In queue: null
Finalizing Weak 6
Finalizing Weak 5
Finalizing Weak 4
Finalizing Weak 3
从结果中,可以看出:
1.垃圾回收器回收优先级别:SoftReference< WeakReference < PhantomReference。
2.当运行垃圾回收方法System.gc时,会先调用目标对象的finalize方法。
3.当某个对象实例 ,只被Reference(包括上面三个派生类)引用的时候,在垃圾回收器回收的时候,被回收。
若这个实例,被Reference和普通引用 同时引用,那么 按照普通引用的垃圾回收规则来,不被回收。
普通引用的垃圾回收规则:
若某对象实例被普通引用 引用(即此对象是可获得的,参考thinking in java的解释),那么不会被垃圾回收器回收。
若某对象实例不被任何普通引用 引用(即此对象是不可获得的,参考thinking in java的解释),那么会被垃圾回收器回收。
参见下面的代码:(摘自thinking in java4ed)
package containers; import java.util.WeakHashMap; class Element{ private String ident; public Element(String id){ ident = id; } public String toString(){ return ident; } public int hashCode(){ return ident.hashCode(); } public boolean equals(Object r){ return r instanceof Element && ident.equals(((Element)r).ident);//此处应有掌声 } protected void finalize(){ System.out.println("Finalizing "+ getClass().getSimpleName()+ " " + ident); } } class Key extends Element{ public Key(String id){ super(id); } } class Value extends Element{ public Value(String id){ super(id); } } public class CanonicalMapping { public static void main(String[] args) { int size= 1000; if (args.length >0) { size= new Integer(args[0]); } Key[] keys= new Key[size]; WeakHashMap<Key, Value> map= new WeakHashMap<Key, Value>(); for (int i = 0; i < size; i++) { Key k= new Key(Integer.toString(i));//Key的实例被普通引用k引用 Value v= new Value(Integer.toString(i));//Value的实例被普通引用v引用 if (i % 3 ==0) { keys[i]= k;//Key的实例被普通引用keys[i]引用,这时,一个Key的实例既被k引用,也被keys[i]引用。 } map.put(k, v);//k引用,v引用自动被WeakHashMap封装为WeakReference引用。 } System.gc();//垃圾回收的时候,对于对象实例(Key的实例和Value的实例)只被Reference(WeakReference)引用的时候,被回收。 //如果这个实例既被Reference引用,也被普通引用引用,则按照普通引用垃圾回收规则来, 不被回收 } }