什么是SoftReference? SoftReference是一个Java类,它代表一个引用,可以被垃圾回收器(GC)回收掉。每一个Java对象都会持有一个其他对象的引用,只要有一个对象持有另一个对象的引用,那么GC就不会回收掉它,只有当我们的程序内存溢出时并且没有其他资源可以释放的时候,GC才会回收掉持有SoftReference的引用,因此,SoftReference非常适合用来打造Cache。
SoftReference
创建一个SoftReference对象
SoftReference<String> ref = new SoftReference<String>("Hello world");
获取数据
String value = ref.get();
if (value == null) {
// 引用已经被GC回收掉了.
// 重新初始化对象.
}
// 使用拿到的数据.......
SoftReference Cache
我们如何使用SoftReference来打造一个Cache?我们使用一个HashMap和java泛型来实现。首先我们创建一个 SoftReferenceCache类,它有两个泛型,一个是Key一个是Value。在构造方法中我们初始化HashMap
public class SoftReferenceCache<K, V> {
private final HashMap<K, SoftReference<V>> mCache;
public SoftReferenceCache() {
mCache = new HashMap<K, SoftReference<V>>();
}
}
为了可以向cache中加入数据,我们写一个put方法,在put方法里面,一个持有SoftReference的对象value被创建出来了,value的类型就是泛型V
public void put(K key, V value) {
mCache.put(key, new SoftReference<V>(value));
}
为了从cache中取出对象我们还得写一个get方法
public V get(K key) {
V value = null;
//首先先从HashMap中根据key取出value,value为一个SoftReference对象
SoftReference<V> reference = mCache.get(key);
//判断如果value不为空
if (reference != null) {
//则调用SoftReference的get方法取出真正的value值
value = reference.get();
}
return value;
}
接下来使用一个例子来说明如何使用我们这个cache
SoftReferenceCache<Integer, Person> mPersonCache =
new SoftReferenceCache<Integer, Person>();
mPersonCache.put(0, new Person("Peter");
mPersonCache.put(1, new Person("Jan");
mPersonCahce.put(2, new Person("Kees");
//我们会得到名字为Jan这个对象
Person p = (Person)mPersonCache.get(1);
下面是SoftReferenceCache完整的代码
/**
* SoftRefenceCache
* @param <K> key键的泛型
* @param <V> value值的泛型
*/
public class SoftReferenceCache<K, V> {
private final HashMap<K, SoftReference<V>> mCache;
public SoftReferenceCache() {
mCache = new HashMap<K, SoftReference<V>>();
}
/**
* 加入一个新的对象到cache中
* @param key
* 键
* @param value
* 要存储的对象
*/
public void put(K key, V value) {
//value对象持有一个SoftReference引用
mCache.put(key, new SoftReference<V>(value));
}
/**
* 从cache中取出数据
* @param key
* 键
* @return 如果cache中不存在则返回null,存在则返回value
*/
public V get(K key) {
V value = null;
//获得value对象
SoftReference<V> reference = mCache.get(key);
if (reference != null) {
//获得value值
value = reference.get();
}
return value;
}
}