当前位置: 首页 > 知识库问答 >
问题:

在什么情况下,尽管lambda的返回类型不同,'thenApply()`与'Thencomose()`是不明确的?

岳嘉容
2023-03-14

我正在学习CompletableFuture。

我不是在问应用()和合成()之间的区别。相反,我想问一个感觉不正确的代码“气味”,以及什么可能真正证明它是正确的。

从我到目前为止看到的CompletableFutures的用法来看,你似乎永远不会拥有这个:

CompletableFuture<String> foo = getSomething().thenApply((result) -> { ... });

也不是这个:

String foo = getSomething().thenCompose((result) -> { ... });

要返回未来,您必须使用thencose(),否则必须使用thenApply()

但从经验来看,语言并没有想出一种方法来消除每次都做出这种明确选择,这似乎很奇怪。例如,难道没有一个方法的返回类型(在编译时)是从lambda中的返回推断出来的吗?然后,也可以在html" target="_blank">编译时给它类似于然后应用或然后组合的属性。

但我相信有一个很好的理由,有单独的方法,所以我想知道为什么。

>

  • 是因为在Java中从lambda推断返回类型很危险还是不可能?(我也是Java新手。)

    是因为在某种情况下,单个方法确实是模棱两可的,而唯一的解决方案是拥有单独的方法吗?(我想可能是嵌套的CompletableFutures或复杂的接口和泛型。)如果是这样,有人能提供一个清晰的例子吗?

    是出于其他原因还是有记录的建议?

  • 共有2个答案

    曾承弼
    2023-03-14

    您对差异的理解是错误的。thenApply和thenCompose都返回CompletableFuture(或者,好吧,CompletionStages)。

    它们之间的区别在于你在<代码>(结果)中隐藏了什么-

    对于应用,您希望该函数返回一个字符串,使整行返回一个完整的未来

    对于撰写,您希望该函数返回一个可完成的未来

    单修德
    2023-03-14

    供参考,这两种方法的签名为:

    <U> CompletableFuture<U>   thenApply(Function<? super T,? extends U> fn)
    <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
    

    <代码>功能

    因此,thenDo的签名类似于:

    <U> CompletableFuture<U> thenDo(Function<? super T,?> fn)
    

    这虽然合法,但使用起来确实很痛苦,因为编译器无法检查fn的返回类型是否正确,并且必须接受任何内容。

    此外,这个thenDo的实现将没有其他选择,只能应用函数并检查返回的对象是否实现了CompletionStage,这(除了速度慢和…令人讨厌的不雅)在不直接的情况下会有实际问题:在可完成的未来调用thenDo时会发生什么

    如果您是java泛型的新手,我的建议是首先专注于了解两件事:

    1. 类型参数的协方差/逆方差(或者更确切地说,缺少协方差/逆方差)。为什么没有列出

    设置好这些后,研究如何通过反射解析类型变量(例如:了解Guava的TypeToken是如何工作的)

    编辑:修复链接

     类似资料:
    • 我的A类是: 另一类B为: 如果我将类A的方法sayHello(int,int)的返回类型从int改为float,它会显示一个错误,因为根据覆盖规则,返回类型也被认为是无效的覆盖和重载。 我不明白为什么java不允许更改返回类型。为什么返回类型也需要相同

    • 问题内容: 我正在使用Hibernate + JPA作为我的ORM解决方案。 我正在使用HSQL进行单元测试,并使用PostgreSQL作为真正的数据库。 我希望能够将Postgres的本机UUID类型与Hibernate一起使用,并在其String表示形式中将UUID与HSQL一起用于单元测试(因为HSQL没有UUID类型)。 我正在为Postgres和HSQL单元测试使用具有不同配置的持久性X

    • line.FlatMap(WordSutil::GetWords)是方法引用中错误的返回类型: 编码方法:

    • 问题内容: 使用的方法引用具有返回类型。但是在下面的示例中,允许不兼容。 如何解决方法声明以确保方法引用类型安全而无需手动强制转换? 用例:类型安全但通用的Builder。 我尝试实现没有注释处理(自动值)或编译器插件(lombok)的通用生成器 问题答案: 在第一个例子,并帮助解决通用参数,并以和分别。 除非您明确声明,否则它并不总是a ,这将导致编译时错误,如第二个示例所示。

    • 我试图使用一个类型族来生成依赖于某个类型级别自然数的约束。下面是这样一个函数: 然后我有一个函数,它有这个约束。 当我试图在模式匹配中使用这个函数时,我的类型族应该产生这个约束,ghc说它不能推导出约束 下面是一个例子: 它会产生错误

    • 问题内容: 我对Swift编码还很陌生,所以如果这个错误是简单的答案,请原谅! 我不断收到一条错误消息,指出“表达式类型在没有更多上下文的情况下是模棱两可的”。 有什么建议? 谢谢! 问题答案: 您可以帮助编译器了解如下信息: