【发布时间】:2013-10-08 17:55:17
【问题描述】:
我有一个关于 Java 泛型的问题。假设我有以下界面:
public static class Something<T> {
public void set(T t) {
}
}
public static interface Manager<T> {
public void add(final String key, final Something<T> o);
public Something<T> get(final String key);
}
使用示例:
final Manager<Number> m = ...;
m.add("key", new Something<Number>());
m.get("key").set(new Integer(5));
我还希望能够将Something<Integer>、Something<Double>、...添加到Manager<Number>。我想说我必须更改 add-function 的签名:
public static interface Manager<T> {
public void add(final String key, final Something<? extends T> o);
public Something<T> get(final String key);
}
final Manager<Number> m = ...;
m.add("key", new Something<Integer>());
m.get("key").set(new Integer(5));
到目前为止,一切都很好。让我们看一下管理器的可能实现:
public static class ManagerImplementation<T> implements Manager<T> {
protected HashMap<String, Something<T>> map = new HashMap<String, Something<T>>();
public void add(final String key, final Something<? extends T> o) {
map.put(key, o); // <--- here
}
public Something<T> get(final String key) {
return map.get(key);
}
}
这失败了,因为您无法将Something<? extends T> 添加到Map<X, Something<T>>。所以让我们改变一下:
public static class ManagerImplementation<T> implements Manager<T> {
protected HashMap<String, Something<? extends T>> map = new HashMap<String, Something<? extends T>>();
public void add(final String key, final Something<? extends T> o) {
map.put(key, o);
}
public Something<T> get(final String key) {
return map.get(key); // <--- here
}
}
这失败了,因为map.get(key) 返回Something<? extends T>,而get 函数需要返回Something<T>,正如接口中定义的那样。
解决这个问题的常用方法是什么?
谢谢!
【问题讨论】:
-
为什么不能把接口中的get方法也改成
public Something<? extends T> get(final String key);呢? -
@HariShankar 这将返回
Something<? extends T>,因此 OP 将无法通过此类引用向set发送任何内容(null除外)。