[英]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.