Reputation: 217
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
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
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
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
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