Java:upcasting Collection <t>到Collection <u super =“”t =“”> </u> </t>

时间:2009-11-19 21:13:50

标签: java generics collections

我有Collection<T>。我有一个类TManager实现了一个接口UManager,它有一个方法getCollection(),需要返回一个Collection<U>,其中U是一个接口,T是一个实现U的类。

除了投射它之外,例如return (Collection<U>)Tcoll;,有更正确的方法来处理这个问题吗?

我在这里控制所有4个类/接口。我将UManager.getCollection声明为

是错误的
public Collection<U> getCollection();

应该是

public Collection<? extends U> getCollection()

4 个答案:

答案 0 :(得分:3)

这取决于你需要对Collection做什么。如果您不需要在返回的集合中放入任何内容,请使用extends参数

  public interface UInterface {

         Collection<? extends UInterface> getCollection();

  }

完成它。如果将来你确实需要添加到集合中,将它包装在一个新的Collection中并添加all就可以完成这项工作,忽略它的性能(对于编译时问题,额外的运行时性能命中)。

但是,如果目的是返回一个可变集合,那么可以在接口中添加一个类型参数:

 public interface UInterface<T extends UInterface> {

        Collection<T> getCollection();

 }

然后你的实施将是:

 public class TClass implements UInterface<TClass> {

        pubic Collection<TClass> getCollection();

 }

这种方法的问题在于,您必须在运行时使用类型参数来使用接口从中获取可变集合,或者引用具体类。

答案 1 :(得分:2)

应该是:

public Collection<U> getCollection();

尝试avoid bounded wildcards in return types

子类只会将返回的引用类型声明为Collection<U>而不是Collection<T>。这将消除你的演员表。

但是,如果你确实看到需要在返回类型中使用有界通配符,那么我猜你将不得不返回Collection<? extends U>并且不需要强制转换。

答案 2 :(得分:1)

我相信你想要:

public Collection<? extends U> getCollection();

您可以找到一些关于此here.

的官方文档 @Jason,你是对的。 doc没有明确地调用返回类型,但确实有效。这是一个演示语法的示例方法:

public Collection<? extends Throwable> getErrors() {
    return new ArrayList<Exception>();
}

答案 3 :(得分:1)

您的topicstart有点令人困惑,因为通用类型通常使用单字符标识符,但您明确提到了接口和类。所以你在寻找这样的东西吗?

interface UManager<T extends UInterface> {
    Collection<T> getCollection();
}

class TManager implements UManager<TClass> {
    public Collection<TClass> getCollection() {
        return Arrays.asList(new TClass(), new TClass());
    }
}

interface UInterface {

}

class TClass implements UInterface {

}