簡短的回答:
您可以使用默認的方法和繼承你的聽衆是隻負責一個類型的事件。
龍回答:
我給的答案是更適合遷移而承受類似品質的普通Java偵聽器:那些具有多個抽象方法,偶爾那些將包含樣板不必要的數額,以及接口,因爲用戶只會對處理一個特定事件感興趣,而不是一次處理所有事件。
與Retrolambda一起使用它們會帶來一些您可能會或可能不會願意採取的折衷。更多關於這個here和here。
基本思想:使監聽器參數成爲用lambda實現的有效目標,必須確保無論監聽器目標類是什麼,它都應該有一個且只有一個抽象方法。 考慮初始類:
public interface CallListener<T> {
void onSuccess(T result);
void onError(String errorMsg);
}
它有幾個抽象方法,所以,使其成爲拉姆達有效分配的目標,我們以「貫徹」所有,但一個方法。我們使用默認的方式做到這一點:
public class CallListeners {
public static interface SuccessListener<T> extends CallListener<T> {
// we implement onError in such way that listener would ignore error event
default void onError(String _ignore) {}
}
public static interface ErrorListener<T> extends CallListener<T> {
default void onSuccess(T result) {}
}
// Methods to "help" compiler infer correct listener type
public void <T> Call<T> success(SuccessListener<T> listener) {
return listener;
}
public void <T> Call<T> error(ErrorListener<T> listener) {
return listener;
}
}
之後,就可以使用上面所有這樣的:
test.SetOnCallListener(
CallListeners.success(argument -> /*your implementation here*/));
或者:
你可以做一個具體的類允許插入其方法的各種(可能可重用的)實現,並且具有工具工廠方法,其中除了一個事件監聽器之外的所有事件監聽器都通過空操作來實現:
public class CallListenerImpl<T> implements CallListener<T> {
private Consumer<T> success; // java.util.function.Consumer
private Consumer<String> error;
public CallListenerImpl(Consumer<? super T> succ, Consumer<String> err) {
success = succ; error = err;
}
void onSuccess(T result) {
success.accept(result);
}
void onError(String err) {
error.accept(err);
}
// Sugary stuffs:
public static <T> CallListenerImpl<T> success(Consumer<T> succ) {
return new CallListenerImpl<>(succ, noOp());
}
public static <T> CallListenerImpl<T> error(Consumer<String> err) {
return new CallListenerImpl<>(noOp(), err);
}
private static <T> Consumer<T> noOp() {
return a -> {};
}
}
不應該這是一個無效的lambda,因爲它有多個抽象方法?我錯過了有關retrolambda的事情嗎? –
請立即檢查問題,@ M.Prokhorov –