我有一个关于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);
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
final Manager<Number> m = ...;
m.add("key", new Something<Number>());
m.get("key").set(new Integer(5));
Run Code Online (Sandbox Code Playgroud)
我也想能够添加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));
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.让我们看看经理的可能实现:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这会失败,因为您无法添加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
}
}
Run Code Online (Sandbox Code Playgroud)
这因为失败map.get(key)的回报Something<? extends T>,而需要一开始函数返回Something<T>,因为在接口中定义.
解决这个问题的常用方法是什么?
谢谢!
在你的类中你总是使用Something<? extends T>,因此在你的public get方法中你必须将内部世界转换为外部世界格式。例如,您可以简单地将结果转换为map.get(key)to Something<T>:
return (Something<T>) map.get(key); // <--- here
Run Code Online (Sandbox Code Playgroud)