List< String>を返す方法put(Object)をマップに送信したメソッドから(例はありません)
質問
次のコードがあります
private Map<KEY, Object> values = new HashMap<KEY, Object>();
public void set(KEY key, Object value) {
values.put(key, value);
}
private Object getObj(KEY key) {
return values.get(key) == null ? key.getDefaultValue() : values.get(key);
}
public List<E> getList(KEY key) {
return (List<E>) getObj(key);
}
マップ内の任意のオブジェクトを送信してから取得できるようにするというアイデアですが、javaのgenereics-partを解決するにはどうすればよいですか?
サンプルコードを次に示します。ここで、リストをマップに保存します。
List<String> list = new ArrayList<String>();
list.add("a string");
session.set(KEY.LIST, list);
リストを再度取得したい:
List<String> list = session.getList(KEY.LIST);
しかし、今私は得る
cannot convert from List<E> to List<String>
明らかな理由によるエラー。
タイプキャストなしでメソッドからList(String)を取得することは可能ですか?この方法は正しいですか?
public List<E> getList(KEY key) {
return (List<E>) getObj(key);
}
解決
型消去*を克服する別のオプションは、戻り値で期待しているオブジェクトクラスへの参照を渡すことです。
また、何らかの型チェックを行う機会があります。
public <E> List<E> getList(KEY key, Class<? extends E> elementClass)
{
Object o = getObj(key);
if ( ! (o instanceof List) ) throw new RuntimeException("Not a list value");
List l = (List)o;
if ( l.size() > 0 && !elementClass.isAssignableFrom( l.get(0) ) ) throw new RuntimeException("List element not valid type");
return (List<E>)l;
}
次のように呼び出します:
List<String> list = session.getList(KEY.LIST, String.class);
*少なくともメソッドの宣言で型消去を克服します。メソッド本体でキャストする必要があります。
他のヒント
type erasure のため、これを解決することはできません。あなたができる最善のことは、キャストがうまくいかないことを絶対に確信しているなら、警告を抑制することです。
指定したキャストは、 getObj
が List
を返すこと以外は何もチェックしないため、警告を生成します。実際、 タイプ消去 -実行時に、文字列を含む List
がありますが、それだけです。
リスト内のすべてが文字列(またはnull)であることを確かに確認できますが、それはO(n)操作です。または、キャストを行い、警告を抑制し、希望することもできます。この場合、非文字列にヒットした場合にのみ例外が発生します。
MultiMapを試すことができます。キーごとに複数の値を保存できます。 Googleには実装があります。 。 Apache commonsにはおそらく実装もあります。
セッションに List
を配置する代わりに、アプリケーションドメインで意味のあるタイプを導入します。たとえば、 List&lt; LineItem&gt;
の代わりに、 Order
:
public final class Order {
private final List<LineItem> lineItems;
[...]
}