java - 如何告诉java泛型类型是函数式接口(interface)?

标签 java generics lambda

我有一个通用功能接口(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/

相关文章:

.net - Linq:如何通过一个表的SUM和另一个表的COUNT进行排序

java - 使用 dispatchevent 生成 mousemove 事件?

java - 获取运行时错误 "java.lang.IllegalStateException: Could not execute method for android:onClick"

c# - 为什么未检测到使用继承类型的泛型类的类约束?

ios - 如何在 Swift 中通过泛型类型构造属性?

c++ - 使用模板化元数存储在类函数中

c++ - 在 clang 和 gcc 中移动可分配的 lambda

c# - NHibernate Native SQL 多重连接

java - 将 Semaphore obj 置于等待状态的方法

Java - <> 有什么用,它的名字是什么?