要说明我的棘手问题,需要一些解释,所以请耐心等待。
我正在为可观察模式设计简约接口,该模式使用可观察类中的管理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>
接受更一般的 {strong} {strong} Listener
,该怎么办? Listener<? super T>
这是有道理的,因为期望? super T
的侦听器也将接受T
(它是 contravariant )。
因此,ListenerHandle
需要区分从其获得的T
的{{1}}和受管理的Observable
的{{1}}:< / p>
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
的{{1}}和 ListenerHandle<? super TO, TO> addListener(Listener<? super TO> listener);
的{{1}}将相同< / i>:
ListenerHandle
因此,我需要一种方法来指定一个以 super 为边界的 labeled 类型参数,以证明该参数的有界泛型类型与返回类型的有界泛型类型。我该怎么办?
答案 0 :(得分:0)
您可以将其设置为TL
,而不是为类型Listener
添加通用参数Listener<? super T>
:
public interface ListenerHandle<T> {
boolean isRemoved();
void remove();
Listener<? super T> managedListener();
Observable<T> containingObservable();
}
public interface Observable<T> {
T get();
void set(T value);
ListenerHandle<T> addListener(Listener<? super T> listener);
}
public interface Listener<T> {
<TO extends T> void onChange(ListenerHandle<TO> handle, TO value);
// or:
// void onChange(ListenerHandle<? extends T> handle, T value);
}
如果您确实需要将TL
参数添加到ListenerHandle
,我认为唯一的方法是static method workaround:
public interface ListenerHandle<TL, TO extends TL> {
boolean isRemoved();
void remove();
Listener<TL> managedListener();
Observable<TO> containingObservable();
}
public interface Observable<TO> {
TO get();
void set(TO value);
// @Deprecated
ListenerHandle<?, TO> addListener(Listener<? super TO> listener); // implies ListenerHandle<? super TO, TO>
@SuppressWarnings("unchecked")
static <TL, TO extends TL> ListenerHandle<TL, TO> addListener(Observable<TO> observer, Listener<TL> listener) {
return (ListenerHandle<TL, TO>) observer.addListener(listener);
}
}
public interface Listener<TL> {
void onChange(ListenerHandle<TL, ?> handle, TL value); // implies ListenerHandle<TL, ? extends TL>
}
您将必须记住永远不要直接调用obs.addListener(lis)
,而要使用Observable.addListener(obs, lis)
。将其标记为@Deprecated
会给您一个警告,但您也需要将其置于所有覆盖方法上。