| 
 | 
 
| 
 
 代码示例 
通过以上的介绍,相信您对java的引用机制以及几种引用方式的异同已经有了一定了解。光是概念,可能过于抽象,下面我们通过一个例子来演示如何在代码中使用Reference机制。 
 
 
 
1     String str = new String("); //① 
2     ReferenceQueue<String> rq = new ReferenceQueue<String>(); //② 
3     WeakReference<String> wf = new WeakReference<String>(str, rq); //③ 
4     str=null; //④取消"hello"对象的强引用 
5     String str1=wf.get(); //⑤假如"hello"对象没有被回收,str1引用"hello"对象 
6     //假如"hello"对象没有被回收,rq.poll()返回null 
7     Reference<? extends String> ref=rq.poll(); //⑥ 
 
 
 
在以上代码中,注意⑤⑥两处地方。假如“hello”对象没有被回收wf.get()将返回“hello”字符串对象,rq.poll()返回null;而加入“hello”对象已经被回收了,那么wf.get()返回null,rq.poll()返回Reference对象,但是此Reference对象中已经没有str对象的引用了(PhantomReference则与WeakReference、SoftReference不同)。 
 
 
 
    引用机制与复杂数据结构的联合应用 
 
 
    了解了GC机制、引用机制,并配合上ReferenceQueue,我们就可以实现一些防止内存溢出的复杂数据类型。 
 
例如,SoftReference具有构建Cache系统的特质,因此我们可以结合哈希表实现一个简单的缓存系统。这样既能保证能够尽可能多的缓存信息,又可以保证Java虚拟机不会因为内存泄露而抛出OutOfMemoryError。这种缓存机制特别适合于内存对象生命周期长,且生成内存对象的耗时比较长的情况,例如缓存列表封面图片等。对于一些生命周期较长,但是生成内存对象开销不大的情况,使用WeakReference能够达到更好的内存管理的效果。 
 
附SoftHashmap的源码一份,相信看过之后,大家会对Reference机制的应用有更深入的理解。 
 
 
 
  1package com.***.widget; 
  2 
  3//: SoftHashMap.java  
  4import java.util.*;  
  5import java.lang.ref.*;  
  6 
  7import android.util.Log; 
  9public class SoftHashMap extends AbstractMap {  
 10  /** The internal HashMap that will hold the SoftReference. */  
 11  private final Map hash = new HashMap();  
 12  /** The number of "hard" references to hold internally. */  
 13  private final int HARD_SIZE;  
 14  /** The FIFO list of hard references, order of last access. */  
 15 private final LinkedList hardCache = new LinkedList();  
 16  /** Reference queue for cleared SoftReference objects. */  
 17  private ReferenceQueue queue = new ReferenceQueue();  
 18 
 19  //Strong Reference number 
 20  public SoftHashMap() { this(100); }  
 21  public SoftHashMap(int hardSize) { HARD_SIZE = hardSize; }  
 22   
 23 
 24  public Object get(Object key) {  
 25    Object result = null;  
 26    // We get the SoftReference represented by that key  
 27    SoftReference soft_ref = (SoftReference)hash.get(key);  
 28    if (soft_ref != null) {  
 29      // From the SoftReference we get the value, which can be  
 30      // null if it was not in the map, or it was removed in  
 31      // the processQueue() method defined below  
 32      result = soft_ref.get();  
 33      if (result == null) {  
 34        // If the value has been garbage collected, remove the  
 35        // entry from the HashMap.  
 36        hash.remove(key);  
 37      } else {  
 38        // We now add this object to the beginning of the hard  
 39        // reference queue.  One reference can occur more than  
 40        // once, because lookups of the FIFO queue are slow, so  
 41        // we don't want to search through it each time to remove <br>< span><br><="" > 43<="" >        ="" >keep recent use object in memory<="" ><br><="" > 44<="" ><="" >        hardcache.addfirst(result); <br><="" > 45<="" >      ="" >if<="" > (hardcache.size() <="" >><="" > hard_size) <="" span><span><br><="" > 46<="" >         ="" > remove the last entry if list longer than hard_size <="" > 47<="" >          hardcache.removelast(); <br><="" > 48<="" }<="" span><="" > <br><="" > 49<="" >     ="" > 50<="" >   ="" > 51<="" >return<="" > result; <br><="" > 52<="" > ="" > 53<="" > 54<="" **<="" > we define our own subclass of softreference which contains <br><="" > 55<="" >  ="" not only the value but also the key to make it easier to find <br><="" > 56<="" the entry in the hashmap after it's been garbage collected. <="" span="">*/</br><>  
 57  private static class SoftValue extends SoftReference {  
 58    private final Object key; // always make data member final  
 59    /** Did you know that an outer class can access private data  
 60     members and methods of an inner class?  I didn't know that! <br>< span><br><="" > 62<="" outer class's private information.  an outer class can also </br><> 63     access private members of an inner class inside its inner  
 64     class. */  
 65    private SoftValue(Object k, Object key, ReferenceQueue q) {  
 66      super(k, q);  
 67      this.key = key;  
 68    }  
 69  }  
 70 
 71  /** Here we go through the ReferenceQueue and remove garbage  
 72   collected SoftValue objects from the HashMap by looking them  
 73   up using the SoftValue.key data member. */  
 74  public void processQueue() {  
 75    SoftValue sv;  
 76    while ((sv = (SoftValue)queue.poll()) != null) {  
 77        if(sv.get()== null){ 
 78            Log.e(", "); 
 79        }else{ 
 80           Log.e(", "); 
 81       } 
 82      hash.remove(sv.key); // we can access private data! 
 83      Log.e(", " + sv.key); 
 84    }  
 85  }  
 86  /** Here we put the key, value pair into the HashMap using  
 87   a SoftValue object. */  
 88  public Object put(Object key, Object value) {  
 89    processQueue(); // throw out garbage collected values first  
 90    Log.e(", " + key); 
 91    return hash.put(key, new SoftValue(value, key, queue));  
 92  }  
 93  public Object remove(Object key) {  
 94    processQueue(); // throw out garbage collected values first  
 95    return hash.remove(key);  
 96  }  
 97  public void clear() {  
 98    hardCache.clear();  
 99    processQueue(); // throw out garbage collected values  
100    hash.clear();  
101  }  
102  public int size() {  
103    processQueue(); // throw out garbage collected values first  
104    return hash.size();  
105  }  
106  public Set entrySet() {  
107    // no, no, you may NOT do that!!! GRRR  
108    throw new UnsupportedOperationException();  
109  }  
110}  
111 
112 
113 |   
 
 
 
 |