Reputation: 4017
The below code will not compile, it says that the method is not applicable for the arguments. The interesting thing is that if I remove one of the arguments (doesn't matter which) then it compiles fine.
public class Test1 {
static Collection<? extends Shape> someColl = new ArrayList<Shape>();
public static void main(String args[]) {
new Test1();
}
public static void Main(String[] args) {
addShape(someColl, new Circle()); //compilation error
}
static <T extends Shape> void addShape(Collection<T> shapes, T shape) {
shapes.add(shape);
}
abstract class Shape {
}
class Rect extends Shape{
}
class Circle extends Shape {
}
}
If I remove one of the method arguments and change it to
addShape(someColl)
and
static <T extends Shape> void addShape(Collection<T> shapes)
OR change it to
addShape(new Circle())
and
static <T extends Shape> void addShape(T shape)
Then it's fine. What's happening here?
Upvotes: 0
Views: 73
Reputation: 440
Maybe you just need to use an interface to be able to add Rects and Cicles in a same collection. If it's what you're trying to do:
public class Test1 {
static Collection<Shape> someColl = new ArrayList<Shape>();
public static void main(String[] args) {
Test1 t = new Test1();
Circle c = t.new Circle();
Rect r = t.new Rect();
addShape(someColl, c);
addShape(someColl, r);
}
static boolean addShape(Collection<Shape> someColl2, Shape shape) {
return someColl2.add(shape);
}
interface Shape {
}
abstract class AbstractShape {
}
class Rect extends AbstractShape implements Shape{
}
class Circle extends AbstractShape implements Shape {
}
}
Upvotes: 0
Reputation: 88707
The problem is that when you call addShape(someColl, new Circle());
there are two different definitions of T
? extends Shape
from Collection<? extends Shape> someColl
Circle
from the second parameterThe other problem with that call is that T
needs to be a concrete type for the second parameter, i.e. you can't define it as ? extends Shape shape
as would be the result when infering T
from Collection<? extends Shape>
.
The method being called addXxxx
suggests you want to add the shape passed as the second parameter to the collection. That, however, won't work with a Collection<? extends Shape>
since the compiler can't know whether a Circle
or any other shape type is allowed.
Assume you'd change the method to accept Shape
as the second parameter: you could pass a Collection<Rect>
and a Circle
which would not fit.
Your best bet in your case would be to change the definition of someColl
to Collection<Shape>
since that's what you do with ArrayList<Shape>
anyways. The compiler would then infer T
to be Shape
and the call should compile.
Upvotes: 1