首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当为Supplier<使用lambda时编译失败?扩展Type>

当为Supplier<使用lambda时编译失败?扩展Type>
EN

Stack Overflow用户
提问于 2015-03-17 16:13:04
回答 2查看 411关注 0票数 2

为什么这不编译?:

代码语言:javascript
复制
import java.util.Optional;

public class Demo {

    Optional<? extends SomeValue> getOption() {
        return Optional.empty();
    }

    void exposure() {
        SomeValue someValue = getOption().orElseGet(() -> new SomeValue());
    }
}

class SomeValue {}

getOption()返回一个Optional<SomeValue>时,它可以正常工作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-17 17:40:26

这是一个相当有限的方法签名的结果:

代码语言:javascript
复制
public T orElseGet(Supplier<? extends T> other) {

在您的例子中,T? extends SomeValue,它是一个未知类型,可以分配给SomeValue (但可能是它的一个子类)。orElseGet的签名意味着允许您的供应商返回一个T的子类型,其总体结果类型为T,但它不允许对公共基本类型的T和供应商返回的类型进行扩展(如果供应商返回SomeValue,而T? extends SomeValue,则公共基类型将为SomeValue)。

可以通过插入允许拓宽类型的操作来修复此问题:

代码语言:javascript
复制
SomeValue someValue = getOption()
  .map(Function.<SomeValue>identity()).orElseGet(() -> new SomeValue());

identity函数不会更改值,但是映射操作允许传入一个消耗更广泛类型的函数,即当实际输入类型为? extends SomeValue而返回类型为SomeValue时,映射函数可以声明使用? extends SomeValue

但是通常情况下,为了避免此类问题,方法的返回类型中不应该有通配符,所以请更改。

代码语言:javascript
复制
Optional<? extends SomeValue> getOption()

代码语言:javascript
复制
Optional<SomeValue> getOption()

请参阅http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html

应该避免使用通配符作为返回类型,因为它迫使使用代码的程序员处理通配符。

票数 4
EN

Stack Overflow用户

发布于 2015-03-17 16:59:54

指定Optional<T>.orElseGet以接受Supplier<? extends T>。但Optional<? extends SomeValue>的含义是,它可以是Optional<MySubClassOfSomeValue>,在这种情况下,Supplier<SomeValue>不会是Supplier<? extends MySubClassOfSomeValue>

orElseGet必须返回Optional元素类型的子类型,而? extends SomeValue可能不是SomeValue

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

https://stackoverflow.com/questions/29104218

复制
相关文章

相似问题

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