私は次のように機能する単純なHashMap
ベースのキャッシュを書いています:
- 要求されたものがキャッシュにある場合は
key
、そのを返しますvalue
。 - 要求された
key
ものがないvalue
場合は、に基づいて生成しkey
、両方を格納し、を返すメソッドを実行しvalue
ます。
コード:
import java.util.HashMap;
abstract class Cache<K, V> extends HashMap<K, V> {
@Override
public V get(Object key) {
if (containsKey(key)) {
return super.get(key);
} else {
V val = getData(key);
put((K)key, val); // this is the line I'm discussing below
return val;
}
}
public abstract V getData(Object key);
}
それはかなり簡単で、うまく機能します。しかし、私は、引数としてではなく、を採用するというSunの決定を嫌います。私はそれについて十分に読んだので、その背後にいくつかの論理的根拠があることを知っています(私は同意しませんが、それは別の話です)。get()
Object
K
キャストのチェックを外す必要があるように見えるので、私の問題はコメント行にあります。型消去のためkey
、型K
(適切なput()
機能に必要)であるかどうかを確認する方法がありません。したがって、メソッドはエラーが発生しやすくなります。
1つの解決策は、「is a」から「HashMap
hasa」の関係に切り替えることです。これは、はるかに優れたクリーンな関係ですが、いくつかの理由でこれをCache
実装できません。Map
コード:
import java.util.HashMap;
import java.util.Map;
abstract class Cache<K, V> {
private final Map<K, V> map = new HashMap<K, V>();
public V get(K key) {
if (map.containsKey(key)) {
return map.get(key);
} else {
V val = getData(key);
map.put(key, val);
return val;
}
}
public abstract V getData(K key);
}
誰かが他の(ハックっぽい)解決策を思い付くことができますか?そうすれば、私はとの点で安全であり続けるCache
ことができますか?Map
get(Object key)
put(K key, V val)
getValue(Key k)
私が考えることができる唯一のことは、に委任するという名前の別のメソッドを作成することget(Object key)
ですが、通常のメソッドの代わりに新しいメソッドを使用するように強制することはできません。