проблема заключается в том, что вы используете необработанный тип по этой линии:
A a;
вы должны указать тип для параметра тип A в (T).
Вы могли бы сделать что-то вроде этого:
A<B> a;
а то А может и не быть общим на всех, если я понимание вашей постановки задачи. Вы, вероятно, хотите сделать что-то вроде этого:
class A<T> {
public void fun(T t) {
}
}
class B<T extends B<T>> {
A<B<T>> a;
public void event() {
a.fun(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);
}
}
Есть несколько вариаций, между этими, которые, возможно, являются полезными, а также. Последний пример является наиболее общим (но, очевидно, и самым сложным).
class A<T extends B<? extends T>>
гарантирует, что параметр типа A является B. Поскольку B сам по себе является общим и имеет этот параметр циклического типа, вам нужно сказать B<? extends T>
(просто говоря, что T здесь не будет работать).
class B<T extends B<T>>
как можно ближе к эмулированию «self type» в Java. Это позволяет B говорить о (почти) конкретном подтипе самого себя. При подклассификации B вы бы сказали что-то вроде «class C extends <B<C>>
». Это полезно, потому что теперь тип C.a
на самом деле A<? super B<C>>
.
В последнем примере бит ? super
полезен только в том случае, если вы планируете подключать B с помощью A
, который не соответствует точному типу B
. Думая в конкретных терминах, предположим, что у вас есть A<Shape>
и Circle
(который распространяется на Shape
, который распространяется на B
). Супер-подстановочный знак позволяет использовать их вместе. Без него вам понадобится A<Circle>
, а не A<Shape>
для вашего Circle
.
Единственное предупреждение, которое я вижу, - это использование A как необработанного типа. Если это не предупреждение, о котором вы говорите, будьте более конкретным и сообщите нам, какой компилятор вы используете. – skaffman