Andreu Alcon
Andreu Alcon

Reputation: 217

generics with super

In

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

Why there is the compilation error

The method react(capture#1-of ? super Elem2) in the type Organic is not applicable for the arguments (Elem)

?

Upvotes: 1

Views: 168

Answers (4)

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78579

By using super you are defining the lower bound of your type parameter. You are saying that the actual type of your organic object is of type Elem2 or one of its super types. As such, the compiler replaces the signature of your react method for Elem2, like this

void react(Elem2 value) {}

So, you cannot pass a new Elem() to your object, because it would require downcasting.

That is, you cannot do this for the same reason you cannot pass a Number to a method requiring an Integer. If you apply downcasting the problem is solved.

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

Alternatively, you can delcare it as

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

Which should work as well.

Upvotes: 2

stefan bachert
stefan bachert

Reputation: 9608

This should work

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

This won't work because they are wildcards (assignment work, calling react won't)

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

You could also do

<F> void react(F e) {
}

Then you could work with wild-cards

I have no clue why you want to work with wild-cards

Upvotes: 0

kandarp
kandarp

Reputation: 5047

The bounded wildcard in List can capture Elem2 and any of its supertypes. Since Elem2 extends Elem, this means that the only types that are currently capture-convertible by List are:

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

Upvotes: 0

user1252434
user1252434

Reputation: 2121

The compiler must not look at the actual value of compound but only on the declaration of it. And ? could be Elem2 itself. And it is supposed to not let you call Organic<Elem2>.react(Elem).

Upvotes: 0

Related Questions