Java泛型:有关具有泛型返回类型(但没有泛型参数)的方法的问题

时间:2018-10-18 13:23:49

标签: java generics java-ee

我经常使用Java泛型,但仍然设法不掌握某些概念。

我有一个简单的类层次结构:

public abstract class KcDashboard{..}
public class KcGroupHsDashboard extends KcDashboard{..}

小帮手

public class ObjectWrapper<O extends Object>{
public ObjectWrapper(){}
public ObjectWrapper( O obj ){
    this.obj = obj;
}
private O obj;
public O unwrap() {
    return obj;
}
public void wrap(O obj) {
    this.obj = obj;
}
}

我有问题的代码:

public <D extends KcDashboard> D getTransientDashboard(){
    ...
    ObjectWrapper<D> wrapp = new ObjectWrapper<>();
    wrapp.wrap( new KcGroupHsDashboard() ); // Gives: The method wrap(D) is not applicable for KcGroupHsDashboard
    return wrapp.unwrap();
    }

无法传递Class<D>作为参数,因为我可以在getTransientDashboard方法中包装并返回不同的类型。

从我会得到的方法中删除类型:

public KcDashboard getTransientDashboard(){
        ...
        ObjectWrapper<KcDashboard> wrapp = new ObjectWrapper<>();
        wrapp.wrap( new KcGroupHsDashboard() );
        return wrapp.unwrap();
        }

可以正确编译。

我知道我想念什么,但是呢?

1 个答案:

答案 0 :(得分:1)

让我们看一个经过稍微修改的示例,以便更好地理解问题:

public <T extends Number> T getTransientDashboard() {
    ObjectWrapper<T> wrapp = new ObjectWrapper<>();
    wrapp.wrap(Integer.valueOf("0")); // Error: Integer cannot be converted to T
    return wrapp.unwrap();
}

其中T可以是Number或其子类之一(例如Double):

ref.<Double>getTransientDashboard();

因此,当您拥有Integer时,您将无法包装ObjectWrapper<Double>

ObjectWrapper<T> wrapp = new ObjectWrapper<>(); // T is Double
wrapp.wrap(Integer.valueOf("0")); // Error ...

这就是为什么发生incompatible types错误的原因-类型安全性是第一位的。最初的示例也是如此。