Generics with extends

给你一囗甜甜゛ 提交于 2020-01-06 15:43:13

问题


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> is not applicable for the arguments (Elem)


回答1:


From 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. (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.

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 ? extends Shape-- an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.

Specifically talking about your solution, you cannot call react with an object of Elem type, as with type 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.




回答2:


modified your method reactas per below, it will work:

void react(Elem e) {

}



回答3:


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. 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. In main method you can do something like this:

    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();

Not sure it is what you wanted but hope it will help



来源:https://stackoverflow.com/questions/9838460/generics-with-extends

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!