Reputation: 5722
Can someone please help me understand why this Java code doesn't compile?
The idea is that A
is a tree-like class for a type T
that takes a collection of children at construction.
Then I define an extension B
of A
that specializes T
for Pair<R,R>
.
class A<T> {
A(T t, Collection<? extends A<? extends T>> cOfAs) {
}
}
class B<R> extends A<Pair<R,R>> { // Pair is just a POJO class
B(Pair<R,R> pair, Collection<? extends B<? extends R>> cOfBs) {
super(pair, cOfBs);
// ERROR: The constructor A<Pair<R,R>>(Pair<R,R>, Collection<capture#1-of ? extends B<? extends R>>) is undefined
}
}
Upvotes: 1
Views: 46
Reputation: 178263
The type of the second parameter doesn't match. The B
constructor takes Collection<? extends B<? extends R>>
, but the superclass constructor takes a Collection<? extends A<? extends T>>
.
You've defined T
to be Pair<R, R>
in your B
class, so instead of R
, use Pair<R, R>
. Also the ? extends
part must match, so change ? extends B<...>
to ? extends A<...>
. The signature of B's constructor now looks like this:
B(Pair<R,R> pair, Collection<? extends A<? extends Pair<R, R>>> cOfBs)
It must be ? extends A
exactly, because ? extends B
may not match ? extends A
. The only way to get this to match is to introduce another type parameter in A
representing the "self" type, and to use it in the second parameter of the constructor.
class A<T, S extends A<T, S>> {
A(T t, Collection<? extends S> cOfAs) {
}
}
Then in B
, supply B<R>
as "self".
class B<R> extends A<Pair<R,R>, B<R>> { // Pair is just a POJO class
B(Pair<R,R> pair, Collection<? extends B<R>> cOfBs) {
super(pair, cOfBs);
}
}
Upvotes: 2
Reputation: 367
The type of second argument of constructor is wrong:
Error:(20, 25) java: incompatible types: java.util.Collection<capture#1 of ? extends Main.B<? extends R>> cannot be converted to java.util.Collection<? extends Main.A<? extends javafx.util.Pair<R,R>>>
To fix it change second argument to Collection<? extends B<R>> cOfBs
Upvotes: 1