The problem is that you're using a raw type on this line:
A a;
You need to specify a type for A's type parameter (T).
You could do something like this:
A<B> a;
but then A might as well not be generic at all, if I'm understanding your statement of the problem. You probably want to do something like this:
class A<T> {
public void fun(T t) {
}
}
class B<T extends B<T>> {
A<B<T>> a;
public void event() {
a.fun(this);
}
}
or even this:
class A<T extends B<? extends T>> {
public void fun(T t) {
}
}
class B<T extends B<T>> {
A<? super B<T>> a;
public void event() {
a.fun(this);
}
}
There are a couple of variations in-between these that are possibly useful as well. The latter example is the most generic (but obviously, also the most complicated).
The class A<T extends B<? extends T>>
is ensuring that the type parameter to A is a B. Since B is itself generic, and has that cyclic type parameter, you end up needing to say B<? extends T>
(simply saying T won't work here).
The class B<T extends B<T>>
is as close as you can get to emulating a "self type" in Java. This lets B talk about the (almost) concrete subtype of itself. When subclassing B you'd say something like "class C extends <B<C>>
". This is useful because now the type of C.a
is actually A<? super B<C>>
.
The ? super
bit in the latter example is only useful if you plan on connecting a B with an A
that isn't for exactly the same type of B
. Thinking in concrete terms, suppose you had an A<Shape>
and a Circle
(which extends Shape
which extends B
). The super-wildcard lets you use them together. Without it you'd need an A<Circle>
rather than an A<Shape>
for your Circle
.