【发布时间】:2019-04-12 02:11:42
【问题描述】:
为了说明我比较棘手的问题,需要一些解释,所以请多多包涵。
我正在为 observable 模式设计极简界面,该模式使用管理 ListenerHandles 而不是 observable 类中的 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>接受更笼统的 Listeners? Listener<? super T>s 是准确的。这是有道理的,因为期望? super T 的侦听器也将接受T(它是逆变的)。
因此,ListenerHandle 需要区分 T 的来源 Observable 和托管 T 的 Listener:
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 为界的 labeled 类型参数,以证明该参数的有界泛型类型与返回类型的有界泛型类型。我怎么能这样做?
【问题讨论】: