空值存放快取小技巧

我們產生很多資料物件或者數值物件 (data objects / value objects) 要放進快取空間 (Cache) 時,遇到無法存放 null 物件的限制。以近期快取 LruCache (Least Recently Used Cache) 為例:

Student cached = cache.get(id);
if (cached == null) {
cached = query(id);
if (cached != null) cache.put(id, cached); // throw exception if put null into cache
}
return cached;

因為 cache 沒有提供 cache.contains(id) 來得知是否有快取,僅能透過cache.get(id) == null 來得知,但如果 query(id) 查無資料也是 null 而且也放不進快取,導致查無資料的編號會快取不到。

解法是設計一個代表空值物件:

Student cached = cache.get(id);
if (cached == Student.EMPTY) return null;
cached = query(id);
if (cached == null) cached = Student.EMPTY;
cache.put(id, cached);
return cached;
public class Student {
public static final Student EMPTY = new Student();
}