我有一个通用的函数接口来向用户询问错误(与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);这不能在与return联机的error: incompatible types: H1 is not a functional interface中编译。
问题是,我能告诉java泛型H1是一个函数式接口吗?或者,我如何让这段代码工作?
发布于 2017-02-11 02:52:46
没有办法告诉编译器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签名实现它是行不通的。
解决方案很简单。只需完全删除子接口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;
};
}https://stackoverflow.com/questions/42007711
复制相似问题