Reputation: 28188
What is wrong with Class A
below that won't allow it to compile?
public class GenericsHell {
interface Shape{}
interface Circle extends Shape {}
interface ShapeHelper<T extends Shape> {
void draw(T shape);
}
class A<T extends Shape> {
A(T shape, ShapeHelper<? extends Shape> helper) {
helper.draw(shape); // Issues not-applicable argument error
}
}
class B {
B(Circle circle, ShapeHelper<Circle> helper) {
helper.draw(circle);
}
}
}
Eclipse gives the following error:
The method draw(capture#1-of ? extends Shape) in the type ShapeHelper<capture#1-of ? extends Shape> is not applicable for the arguments (T)
Upvotes: 0
Views: 159
Reputation: 122489
Remember PECS (producer extends
, consumer super
).
helper
is a consumer (you pass something to it), hence it cannot be extends
. Perhaps it could be super
, but I don't know if that makes sense in this case
Upvotes: 0
Reputation: 2496
The method draw(capture#1-of ? extends GenericsHell.Shape) in the type GenericsHell.ShapeHelper<capture#1-of ? extends GenericsHell.Shape> is not applicable for the arguments (T)
The problem is that in your declaration, shape is of type T, but you request a ShapeHelper of type <? extends Shape> which means that one could pass as argument a ShapeHelper where S and T are distinct.
You would then call helper<S>.draw(shape<T>);
which doesn't make sense.
A correct implementation for this method would be:
class A<T extends Shape> {
A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
Which ensures that the shape and the shape helper are of compatible types.
Upvotes: 2
Reputation: 236124
Try this instead:
class A<T extends Shape> {
A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
Upvotes: 0
Reputation: 80633
You defined your generic parameter for Class A as one thing, but then tried to use it in an incompatible fashion in your constructor (<T extends Shape>
is not the same thing as <? extends Shape>
. To get your code to compile change it to consistently use your already defined generic parameter:
class A<T extends Shape> {
public A(T shape, ShapeHelper<T> helper) {
helper.draw(shape);
}
}
As an aside, your code doesn't generate the error message you showed in your question. Rather it would be something more like this:
The method draw(capture#1-of ? extends GenericsHell.Shape) in the type GenericsHell.ShapeHelper is not applicable for the arguments (T)
Upvotes: 3
Reputation: 6153
Would be important to see your call to A
. But it seems like you did something like A<Integer>
. But T
must extend Shape
according to your class declaration.. and Integer
doesn't. So either change <? extends Shape>
to <T>
or provide a type that is a Shape
to A
Upvotes: 1