[英]How to tell java that a generic type is a functional interface?
我有一個通用的功能接口,向用戶詢問錯誤(與java.util.function.Function完全相同)和一些參數化子接口:
@FunctionalInterface
public interface Handler<Err,Resp> {
public Resp handle(Err param);
}
@FunctionalInterface
public interface RecoverableErrorHandler<Err> extends Handler<Err, RecoverableErrorResult > {}
@FunctionalInterface
public interface RetryIgnoreErrorHandler<Err> extends Handler<Err, RetryIgnoreAbortResult> {}
我想通過將處理程序包裝到另一個處理程序中來向每個處理程序添加日志記錄:
private <Err,Resp,H1 extends Handler<Err,Resp> > H1 addLogToHandler(String s, H1 h) {
return (Err arg) -> {
Resp res = h.handle(arg);
logger.info(s+" returned "+res);
return res;
};
}
// some code omitted
RecoverableErrorHandler<String> netErrorHandler = ... // shows dialog and asks user what to do
netErrorHandler = addLogToHandler("Network Error handler", netErrorHandler);
這不會error: incompatible types: H1 is not a functional interface
編譯error: incompatible types: H1 is not a functional interface
與return
聯機error: incompatible types: H1 is not a functional interface
。
問題是,我可以告訴Java通用H1
是功能接口嗎? 或者,如何使此代碼起作用?
沒有辦法告訴編譯器H1
應該是功能接口,實際上,您甚至無法告訴它H1
應該是接口。
考慮它時,您可能會注意到,即使您能夠將H1
限制為擴展Handler<Err,Resp>
的功能接口,也無法保證此類型的功能類型與代碼中的lambda表達式兼容。
例如,以下將是滿足約束的類型:
@FunctionalInterface
public interface Foo<E,R> extends Handler<E,R>, Runnable {
default R handle(E param) { run(); return null; }
}
這是一個功能性的接口,它擴展了Handler
,但嘗試在addLogToHandler
使用(Err) -> Resp
簽名來實現它是addLogToHandler
。
解決方案很簡單。 只需完全刪除子接口RecoverableErrorHandler<Err>
和RetryIgnoreErrorHandler<Err>
。 與使用Handler<Err,RecoverableErrorResult>
resp相比,它們沒有任何優勢。 直接Handler<Err,RetryIgnoreAbortResult>
。
消除子類型后,可以將方法更改為
private <Err,Resp> Handler<Err,Resp> addLogToHandler(String s, Handler<Err,Resp> h) {
return arg -> {
Resp res = h.handle(arg);
logger.info(s+" returned "+res);
return res;
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.