繁体   English   中英

具有扩展的泛型

[英]Generics with extends

在:

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

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

class Elem {}

为什么会出现以下编译错误?

类型Organic<capture#1-of ? extends Elem>的方法react(capture#1-of ? extends Elem) Organic<capture#1-of ? extends Elem>不适用于参数( Elem

来自http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

列表是有界通配符的示例。 代表未知类型,就像我们之前看到的通配符一样。 但是,在这种情况下,我们知道该未知类型实际上是Shape的子类型。 (注意:它可以是Shape本身,也可以是某些子类;它不需要扩展Shape。)我们说Shape是通配符的上限。

与往常一样,使用通配符的灵活性要付出一定的代价。 代价是,现在在方法主体中写入形状是非法的。 例如,这是不允许的:

public void addRectangle(List<? extends Shape> shapes) {
    // Compile-time error!
    shapes.add(0, new Rectangle());
}

您应该能够弄清楚为什么不允许使用上面的代码。 shapes.add()的第二个参数的类型是? 扩展Shape-Shape的未知子类型。 由于我们不知道它是什么类型,所以我们不知道它是否是Rectangle的超类型。 它可能是也可能不是这种超类型,因此在此处传递Rectangle是不安全的。

具体说说您的解决方案,您不能使用Elem类型的对象(如Organic<? extends Elem>来调用react Organic<? extends Elem> Organic<? extends Elem>您可以合法地分配compound = new Organic<ElemSubClass>() -然后由于无法调用它传递超类对象,因此react会导致编译错误。

如下修改了您的方法reactas,它将起作用:

void react(Elem e) {

}

'? 当您要允许用户仅将SomeClass或其子类作为通用参数传递时,将使用extended SomeClass'定义通用类型。 这意味着您可以执行以下操作:

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

如果您希望将Organic与Elem的子类一起参数化。 在main方法中,您可以执行以下操作:

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

据我所知,无需使用

Organic<? extends Elem>

在方法主体中。

完整代码:

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

static void main(String[] args) {
    Organic<Elem> compound = new Organic<Elem>();
    compound.react(new Elem());
   }
}
class Elem {}
class ElemSubClass extends Elem {} // if you need

此外,您必须在表达式的左右部分使用相同的泛型类型。 这是不合法的:有机化合物= new Organic();

不确定这是您想要的东西,但希望能对您有所帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM