如何使用方法引用作为将来的回调



当我尝试使用这样的东西时

class Example {
    ...
    private Future<String> asyncMethod() {
        ...
        return somePromise;
    }
    private static void callback(Future<String> future) {
        System.out.println(future.getNow());
    }
    public static void main(String[] args) {
        asyncMethod().addListener(Example::callback);
    }
}

我收到错误

Example.java:[17,34] incompatible types: invalid method reference
   incompatible types: io.netty.util.concurrent.Future<capture#1 of ? super java.lang.String>
   cannot be converted to io.netty.util.concurrent.Future<java.lang.String>

匿名类作为侦听器没有错误

asyncMethod().addListener(new GenericFutureListener<Future<String>>() {
    @Override
    public void operationComplete(Future<String> future) throws Exception {
        System.out.println(future.getNow());
    }
});

但它是丑陋和冗长的:(我能做些什么来以最优雅的方式解决这个问题?

可以强制转换方法引用

asyncMethod().addListener((GenericFutureListener<Future<String>>) Example::callback);

它不那么冗长,但仍然不完美。要稍微改进此解决方案,您可以将长类型定义移动到功能接口

class Example {
    @FunctionalInterface
    private interface Callback extends GenericFutureListener<Future<String>> {
        void operationComplete(Future<String> future) throws Exception;
    }
    private static void callback(Future<String> future) {
        System.out.println(future.getNow());
    }
    public static void main(String[] args) {
        asyncMethod().addListener((Callback) Example::callback);
    }
}

或者,您可以使用类型化参数将回调包装为 lambda

asyncMethod().addListener((Future<String> f) -> callback(f));

也许可以做得更好,IDK。

您拥有的选项是:

  1. 使用 lambda(比完全匿名类短,但仍然不是最佳的):

asyncMethod().addListener((GenericFutureListener<Future<String>>) future -> Application.callback(future))

  1. 将回调参数修复为:

private static void callback(Future<? super String> future) {

从简单的Future<String> future,这样你也可以使用回调。

注意:如果您对? extends vs ? super泛型问题感到困惑,出于同样的原因,我将此SO帖子添加为书签。

最新更新