Java - 泛型和通配符以及接口与实现

use*_*566 6 java generics

我有一个关于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>,因为在接口中定义.

解决这个问题的常用方法是什么?

谢谢!

Las*_*ame 3

在你的类中你总是使用Something<? extends T>,因此在你的public get方法中你必须将内部世界转换为外部世界格式。例如,您可以简单地将结果转换为map.get(key)to Something<T>

return (Something<T>) map.get(key); // <--- here
Run Code Online (Sandbox Code Playgroud)