我有一个通用功能接口(interface)来询问用户错误(与 java.util.function.Function 非常相同)和一些参数化子接口(interface):
@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);
这不会编译并显示错误:不兼容的类型:H1不是功能接口(interface)
与返回
一致。
问题是,我可以告诉java通用H1
是一个函数式接口(interface)吗?或者,我该如何让这段代码工作?
最佳答案
没有办法告诉编译器 H1
应该是一个函数式接口(interface),事实上,你甚至不能告诉它 H1
应该是一个接口(interface)。
当您思考时,您可能会注意到,即使您能够限制 H1
成为扩展 Handler<Err,Resp>
的功能接口(interface),无法保证此类型具有与代码中的 lambda 表达式兼容的函数类型。
例如,以下是满足约束的类型:
@FunctionalInterface
public interface Foo<E,R> extends Handler<E,R>, Runnable {
default R handle(E param) { run(); return null; }
}
这是一个函数式接口(interface),它扩展了 Handler
,但尝试在 addLogToHandler
内实现它与 (Err) -> Resp
签名不起作用。
解决办法很简单。只需删除子接口(interface) RecoverableErrorHandler<Err>
和RetryIgnoreErrorHandler<Err>
完全地。与使用 Handler<Err,RecoverableErrorResult>
相比,它们没有任何优势。分别。 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;
};
}
关于java - 如何告诉java泛型类型是函数式接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42007711/