为什么要将子类对象的子类集合转换为java中不允许的超类对象的超类集合?

时间:2012-03-23 00:08:47

标签: java generics

代码也位于https://github.com/timp21337/java-generics-example

package a;

import java.util.List;

public interface Container<T> {
  List<T> getThings();
}

public class ContainerContainer {
  public Container<Thing> getThingContainer() {
    return new ThingContainer<Thing>();
  }
}

public class ThingContainer<T extends a.Thing> implements Container<T> {
  @Override
  public List<T> getThings() {
    return null;
  }
}

public class Thing {
}

包b

package b;
import java.util.List;

public class ContainerContainer extends a.ContainerContainer {
  ThingContainer<Thing> thingContainer = new ThingContainer<Thing>();
  @SuppressWarnings("unchecked")
  public a.Container<a.Thing> getContainer() {
    return (a.Container<a.Thing>)(Object)thingContainer; //YUCK
  }
}

public class ThingContainer<T extends a.Thing> 
     implements a.Container<T> {
  @Override
  public List<T> getThings() {
    return null;
  }
}

public class Thing extends a.Thing {
}

我的问题是,当它是a.ThingContainer的子类并且它包含的东西是a.Thing的子类时,为什么我必须强制b.ThingContainer(在上面标记为YUCK)?

1 个答案:

答案 0 :(得分:1)

让我们考虑一个更简单的例子,删除所有不相关的细节。 (在此,我们将使用b.Thing代替String,而不是a.Thing,我们将使用Object; StringObject的子类所以它是类似的。我们将使用a.Container而不是List。容器的子类化是无关紧要的,正如您将看到的那样。)如果您能理解为什么这个例子不起作用,那么你会理解你的问题。

List<String> foo = new ArrayList<String>();
List<Object> bar = foo; // why doesn't this work?