2010-11-21 13 views
4

これの詳細を消さなければなりませんが、基本的にはオブジェクトのコレクションを返す高価な操作の結果をキャッシュしようとしていますが、これらの個々のオブジェクトの型はコンパイル時には分かりませんベースクラス)。検索時のチェックされていないキャストを避けるために、ジェネリック型をキャッシュに保存するにはどうすればよいですか?

public class SomeClass 
{ 
    private static final Map<Integer,Collection<? extends SomeBaseClass>> theCache = new HashMap<Integer,Collection<? extends SomeBaseClass>>(); 

    public <T extends SomeBaseClass> Collection<T> theMethod(Class<T> theClass, int index) 
    { 
     if (theCache.containsKey(index)) 
     { 
      return (Collection<T>) theCache.get(index); 
     } 
     else 
     { 
      Collection<T> result = someExpensiveOperation(theClass, index); 
      theCache.put(index, result); 
      return result; 
     } 
    } 

    // ... 

} 

コードだけで、呼び出し側でメソッドに渡されたクラスの引数は、以前の呼び出しによって渡さ1と(同一である必要があります)互換性があることを信頼にそれを取っているので、ここではキャッシュ検索が未チェックのキャストであります最初にキャッシュにオブジェクトを作成しました。

このチェックされていないキャストは避けることができるように、オブジェクト自体と一緒に実際のクラスをキャッシュするいくつかの方法やデザインパターンがありますか?

答えて

3

この動作は直接サポートされていません。キャッシュは、個々の要素が含まれています、あなたはClass.cast()を使用できる場合

は、それが不一致の場合のClassCastExceptionをスロー:

private Map<Integer, ?> cache = ...; 

public <T> T get(Integer id, Class<T> c) { 
    return c.cast(cache.get(id)); 
} 

を、それはより複雑になり、キャッシュされたコレクションの場合。あなたが実際に未チェックのキャストを避けたい場合は、Class.cast()を経由して、それを新しいコレクションを作成して移入することができます

Collection<T> result = ...; 
for (Object o: theCache.get(index)) 
    result.add(theClass.cast(o)); 
return result; 

他のアプローチとしては、例えば、グアバのCollections2.transform()使用してコレクションのビュー「をチェックし」作成:

public class Cast<T> implements Function<Object, T> { 
    private Class<T> type; 
    public Cast(Class<T> type) { 
     this.type = type; 
    } 

    public T apply(Object in) { 
     return type.cast(in); 
    } 
} 

return Collections2.transform(theCache.get(index), new Cast<T>(theClass)); 
0

これを処理する方法は数多くあります。

class TypedList<T> extends ArrayList<T> { 

    private Class<T> type; 

    TypedList(Class<T> type) { 
     super(); 
     this.type = type; 
    } 

    Class<T> getType() { 
     return type; 
    } 
} 

とsomeExpensiveOperation()はその結果を返すために、このクラスを使用していることを確認してください:その要素の型を保存するコレクションクラスを作成する - ここで私がやるだろうものです。こうすることで、キャッシュ項目を取得するときに型を問い合せることができます。

+0

これは静的キャッシュでは役に立ちません。 – BalusC

関連する問題