简体   繁体   English

具有扩展的泛型

[英]Generics with extends

In: 在:

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 {}

Why do I get the following compilation error? 为什么会出现以下编译错误?

The method react(capture#1-of ? extends Elem) in the type Organic<capture#1-of ? extends Elem> 类型Organic<capture#1-of ? extends Elem>的方法react(capture#1-of ? extends Elem) Organic<capture#1-of ? extends Elem> is not applicable for the arguments ( Elem ) Organic<capture#1-of ? extends Elem>不适用于参数( Elem

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

List is an example of a bounded wildcard. 列表是有界通配符的示例。 The ? stands for an unknown type, just like the wildcards we saw earlier. 代表未知类型,就像我们之前看到的通配符一样。 However, in this case, we know that this unknown type is in fact a subtype of Shape. 但是,在这种情况下,我们知道该未知类型实际上是Shape的子类型。 (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard. (注意:它可以是Shape本身,也可以是某些子类;它不需要扩展Shape。)我们说Shape是通配符的上限。

There is, as usual, a price to be paid for the flexibility of using wildcards. 与往常一样,使用通配符的灵活性要付出一定的代价。 That price is that it is now illegal to write into shapes in the body of the method. 代价是,现在在方法主体中写入形状是非法的。 For instance, this is not allowed: 例如,这是不允许的:

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

You should be able to figure out why the code above is disallowed. 您应该能够弄清楚为什么不允许使用上面的代码。 The type of the second parameter to shapes.add() is ? shapes.add()的第二个参数的类型是? extends Shape-- an unknown subtype of Shape. 扩展Shape-Shape的未知子类型。 Since we don't know what type it is, we don't know if it is a supertype of Rectangle; 由于我们不知道它是什么类型,所以我们不知道它是否是Rectangle的超类型。 it might or might not be such a supertype, so it isn't safe to pass a Rectangle there. 它可能是也可能不是这种超类型,因此在此处传递Rectangle是不安全的。

Specifically talking about your solution, you cannot call react with an object of Elem type, as with type Organic<? extends Elem> 具体说说您的解决方案,您不能使用Elem类型的对象(如Organic<? extends Elem>来调用react Organic<? extends Elem> Organic<? extends Elem> you can legally assign compound = new Organic<ElemSubClass>() - and then react will cause compile error as you cannot call it passing a super class object. Organic<? extends Elem>您可以合法地分配compound = new Organic<ElemSubClass>() -然后由于无法调用它传递超类对象,因此react会导致编译错误。

modified your method reactas per below, it will work: 如下修改了您的方法reactas,它将起作用:

void react(Elem e) {

}

The '? '? extends SomeClass' is used in defining generic types when you want to allow user to pass only SomeClass or it's subclasses as a generic parameter. 当您要允许用户仅将SomeClass或其子类作为通用参数传递时,将使用extended SomeClass'定义通用类型。 It means you can do this: 这意味着您可以执行以下操作:

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

if you want Organic to be parametrized with subclasses of Elem. 如果您希望将Organic与Elem的子类一起参数化。 In main method you can do something like this: 在main方法中,您可以执行以下操作:

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

as i know there's no need to use 据我所知,无需使用

Organic<? extends Elem>

in method body. 在方法主体中。

Entire code: 完整代码:

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

Moreover you have to use the same generic types in both left and right part of expression. 此外,您必须在表达式的左右部分使用相同的泛型类型。 This is illehal: Organic compound = new Organic(); 这是不合法的:有机化合物= new Organic();

Not sure it is what you wanted but hope it will help 不确定这是您想要的东西,但希望能对您有所帮助

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

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