java标签一个泛型类型参数,以超级
为了说明我的棘手问题,需要一点解释,所以请耐心听我说
我正在为一个可观察模式设计极简界面,该模式在可观察类中使用管理ListenerHandles
而不是removeListener(...)
方法
这就是想法:
public interface ListenerHandle<T> {
boolean isRemoved();
void remove();
Listener<T> managedListener();
Observable<T> containingObservable();
}
public interface Observable<T> {
T get();
void set(T value);
ListenerHandle<T> addListener(Listener<T> listener);
}
public interface Listener<T> {
void onChange(ListenerHandle<T> handle, T value);
}
现在这一切都很好
但是如果我想Observable<T>
接受更一般的Listener
呢确切地说,是强的。这是有道理的,因为期望? super T
的侦听器也会接受T
(它是逆变的)
因此,ListenerHandle
需要区分从Observable
获得的T
和管理的Listener
的T
:
public interface ListenerHandle<TL, TO> {
// ...
Listener<TL> managedListener();
Observable<TO> containingObservable();
}
public interface Observable<TO> {
// ...
<TL> ListenerHandle<TL, TO> addListener(Listener<TL> listener);
}
public interface Listener<TL> {
void onChange(ListenerHandle<TL, ? extends TL> handle, TL value);
}
尽管这些接口将被编译,但我们知道TL
<TL> ListenerHandle<TL, TO> addListener(Listener<TL> listener);
它有点太泛化了,因为它现在可以是任何东西。然而,Observable
应该只能接受期待TO
或其超类型的侦听器:
<TL super TO> ListenerHandle<TL, TO> addListener(Listener<TL> listener);
这将不起作用,因为super
只能用于通配符。所以另一个选择是:
ListenerHandle<? super TO, TO> addListener(Listener<? super TO> listener);
然而,在这种情况下,调用者将丢失返回的ListenerHandle
? super TO
和listener
? super TO
将是相同的信息:
Observable<Number> o = ...;
Listener<Object> l = ...;
// does not work, but should (since we know that we passed a Listener<Object>)
ListenerHandle<Object, Number> h = o.addListener(l);
// works but Object is now generalized to ? super Number
ListenerHandle<? super Number, Number> h2 = o.addListener(l);
l = h2.managedListener(); // fails because ? super Number is not (necessarily) Object
因此,我需要一种方法来指定一个以super为界的标记的类型参数,以证明参数的有界泛型类型与返回类型的有界泛型类型相同。我怎么能这么做
# 1 楼答案
不必为
Listener
类型添加泛型参数TL
,您可以将其设置为Listener<? super T>
:如果确实需要将
TL
参数添加到ListenerHandle
,我认为唯一的方法是static method workaround:你必须记住永远不要直接调用
obs.addListener(lis)
,而是使用Observable.addListener(obs, lis)
。将其标记为@Deprecated
会给您一个警告,但您也需要将其应用于所有重写方法