超级仿制药

时间:2012-03-23 12:05:44

标签: java generics super

public class Organic<E> {
    void react(E e) {
    }

    static void main(String[] args) {
        Organic<? super Elem2> compound = new Organic<Elem>();
        compound.react(new Elem());
    }
}

class Elem {}

class Elem2 extends Elem {}

为什么会出现编译错误

  

有机类型中的方法反应(捕获超级Elem2中的#1 - )不适用于参数(Elem)

4 个答案:

答案 0 :(得分:2)

通过使用super,您可以定义类型参数的下限。您说有机对象的实际类型是Elem2类型或其超类型之一。因此,编译器会替换Elem2的react方法的签名,如此

void react(Elem2 value) {}

所以,你不能将新的Elem()传递给你的对象,因为它需要向下转换。

也就是说,由于无法将Number传递给需要Integer的方法,因此无法执行此操作。如果你应用向下转换,问题就解决了。

public static void main(String[] args) {
    Organic<Object> all = new Organic<Object>();
    Organic<? super Elem2> other = all;

    Elem a = new Elem2();
    other.react((Elem2)a);
}

或者,您可以将其视为

    Organic<? super Elem> other = ...;

哪个也应该有用。

答案 1 :(得分:0)

编译器不能查看复合的实际值,而只能查看它的声明。 ?本身可能是Elem2。它不应该让你打电话给Organic<Elem2>.react(Elem)

答案 2 :(得分:0)

List中的有界通配符可以捕获Elem2及其任何超类型。由于Elem2扩展了Elem,这意味着List当前可捕获的唯一类型是:

List<Elem2>
List<Elem>
List<Object>

答案 3 :(得分:0)

这应该有效

    Organic<Elem> compound = new Organic<Elem>();

这不起作用,因为它们是通配符(赋值工作,不会调用react)

  Organic<?> compound = new Organic<Elem>();
  Organic<? extends Elem> compound = new Organic<Elem>();
  Organic<? super Elem2> compound = new Organic<Elem>();

您也可以

<F> void react(F e) {
}

然后你可以使用外卡

我不知道你为什么要使用外卡