首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java CompletionStage to CompletionStage<Either>类型丢失

Java CompletionStage to CompletionStage<Either>类型丢失
EN

Stack Overflow用户
提问于 2017-07-21 01:22:41
回答 1查看 1.2K关注 0票数 0

假设我有这个方法:

代码语言:javascript
复制
public CompletionStage<SomeClass> getData() {
    CompletableFuture<SomeClass> future = new CompletableFuture<>();

    return CompletableFuture.runAsync(() -> {
        // Fetch data from some source
        // Then either
        // future.complete(data);
        // or fail
        // future.completeExceptionally(e);
    });

    return future;
}

现在我想要有一个方法,它调用getData,进行操作,然后返回一个CompletionStage<Either<ErrorResponse, Data>>

代码语言:javascript
复制
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
    return getData()
       .thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
       .exceptionally(e -> Either.left(ErrorResponse.create(e)));
}

当我这样做时,exceptionally中的类型会丢失,并且编译器认为我返回的是类型Either<Object, Data>

但是,如果我将代码更改为:

代码语言:javascript
复制
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
    CompletableFuture<Either<ErrorResponse, Data>> future = new CompetableFuture<>();

    CompletableFuture.runAsync(() -> {
        getData()
           .thenCompose(d -> future.complete(Either.right(d)));
           .exceptionally(e -> 
               future.complete(Either.left(ErrorResponse.create(e)))
    });

    return future;
}

那么它工作得很好。为什么类型丢失了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-21 02:38:53

你有

代码语言:javascript
复制
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
    return getData()
       .thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
       .exceptionally(e -> Either.left(ErrorResponse.create(e)));
}

thenCompose是一个泛型方法,但是您没有提供足够的类型信息来推断您希望将其类型参数U绑定到Either<ErrorResponse, Data>。对exceptionally的调用(即使它是泛型的)也不能向thenCompose的调用反馈类型信息。

目前,它为Either的第一个类型参数推断Object。因此,thenCompose返回一个CompletionStage<Either<Object, Data>>。该参数将传播到exceptionally。由于CompletionStage<Either<Object, Data>>不是CompletionStage<Either<ErrorResponse, Data>>,因此对于返回值来说,它是无效类型。

可以通过提供显式类型参数来添加必要的类型信息。

代码语言:javascript
复制
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
    return getData()
       .<Either<ErrorResponse, Data>>thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
       .exceptionally(e -> Either.left(ErrorResponse.create(e)));
}

或者更接近有问题的调用

代码语言:javascript
复制
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
    return getData()
       .thenCompose(d -> CompletableFuture.completedFuture(Either.<ErrorResponse, Data>right(d)))
       .exceptionally(e -> Either.left(ErrorResponse.create(e)));
}

现在Java不需要去尝试和猜测了。它知道你的意思。

或者,我会使用CompletableFuture#handle来处理异常情况。

代码语言:javascript
复制
return getData()
            .handle((d, e) -> {
                if (e == null) {
                    return Either.right(d);
                }
                return Either.left(ErrorResponse.create(e));
            });
}

类型信息是自包含的。剩下的主要是意见问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45221337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档