V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mightofcode
V2EX  ›  Java

JAVA8 的 Optional 是鸡肋

  •  
  •   mightofcode · 2021-01-25 15:00:29 +08:00 · 12405 次点击
    这是一个创建于 1158 天前的主题,其中的信息可能已经有所发展或是发生改变。
    对于处理 NPE 问题基本没有帮助

    不使用 Optional,你得判空
    使用 Optional,你还是得判空,只是换了一种形式
    引入 Optional 降低代码可读性,代码变得丑陋

    我在工作中从没见到有项目使用 Optional
    除了使用 java stream 不得不用到 Optional

    本质上 java 要在 null 上做优化只能通过底层语言设计上做改进(比如 Rust ),然而由于兼容性的需要,这条路已经走不通了
    第 1 条附言  ·  2021-01-25 18:00:21 +08:00
    1,Optional 会有个警告提示你判空,但是这个只是警告,是非强制的

    2,没有 Optional 我可以选择判空、不判空,有了 Optional 我还是可以选择判空、不判空,只是多了个警告而已,而且代码还变难读了!

    3,入参用 Optional 还是不用?如果真这么好用,那么入参也应该用用起来啊,但是稍微想想就知道入参绝不适合用 Optional

    Optional 解决了一个无关紧要的小问题,带来的是可读性的下降,真的是鸡肋
    118 条回复    2021-01-27 20:09:28 +08:00
    1  2  
    Jooooooooo
        1
    Jooooooooo  
       2021-01-25 15:01:32 +08:00
    optional 强制判空, 还是有点用的
    finab
        2
    finab  
       2021-01-25 15:03:00 +08:00
    习惯就还挺好的,optional 用习惯了后,发现挺舒服的,现在写没有 optional 特性的语言代码时都有点不习惯了
    Jirajine
        3
    Jirajine  
       2021-01-25 15:05:26 +08:00 via Android   ❤️ 2
    optional 存在的意义就是通过静态检查强制你处理为空时的情况。rust 也是这样做的。
    fishCulturer
        4
    fishCulturer  
       2021-01-25 15:05:38 +08:00
    感觉判空这块还是工具包香
    yuhuan66666
        5
    yuhuan66666  
       2021-01-25 15:06:46 +08:00
    强制判空,怕你忘,对于多人协作开发,返回值加一个,挺好用的,我就喜欢用
    sampeng
        6
    sampeng  
       2021-01-25 15:12:05 +08:00   ❤️ 3
    自己水平不够就认为没用?
    感情你工作这么久从来没有或者没见过空指针?
    现在从语言层面消灭空指针不都是 optional 的方式么?
    guyeu
        7
    guyeu  
       2021-01-25 15:12:27 +08:00
    问好语法糖和 Optional 又有什么本质区别呢?我觉得 Optional 最重要的意义是提高空返回值的成本,促使程序员使用有意义的返回值代替空,只有在空有意义的情况下才返回空,这样一来,现有的绝大多数的判空就不需要写了。
    mxT52CRuqR6o5
        8
    mxT52CRuqR6o5  
       2021-01-25 15:13:05 +08:00
    你这不是 Optional 的问题,而是没有类似 Kotlin 中 Safe Calls 运算符的问题
    sampeng
        9
    sampeng  
       2021-01-25 15:14:13 +08:00
    rust 哪门子的底层语言设计上做的改进。本质上 rust 的 Option 和 Optional 的实现有任何区别不成?只是 java 有历史包袱不能让你强制所有地方都用 optional 或者具体的值。rust 没这个负担,所以可以提供?的语法糖。在没有?语法糖的时候 rust 判断 option 也是写的很恶心的
    huifer
        10
    huifer  
       2021-01-25 15:17:46 +08:00
    private static Optional optional(){
    return null;
    }

    public static void main(String[] args) {

    System.out.println(optional().isPresent());

    }

    使用的时候是否要对 `Optional` 判空呢?
    yuanxiaosong
        11
    yuanxiaosong  
       2021-01-25 15:19:30 +08:00   ❤️ 6
    随便百度了一个例子,可以试试改成不用 Optional 需要多少代码,少用 isPresent 和 get,多使用 map 、filter 、orElse,多使用 Function 、Supplier 和 Consumer 来解决问题:

    Optional
    .ofNullable(someVariable)
    .map(this::findOtherObject)
    .filter(this::isThisOtherObjectStale)
    .map(this::convertToJson)
    .map(String::trim)
    .orElseThrow(() -> new RuntimeException("something went horribly wrong."));

    代码来源: https://www.jdon.com/52008
    11wangyaoda
        12
    11wangyaoda  
       2021-01-25 15:24:32 +08:00 via Android   ❤️ 5
    optional 最有意思的是 optional 自己有可能是 null
    chendy
        13
    chendy  
       2021-01-25 15:28:36 +08:00
    如果是接 orThrow 直接报错的情况还好
    如果是接 orElse(null) 就显得很多余了
    yazinnnn
        14
    yazinnnn  
       2021-01-25 15:36:09 +08:00
    Optional.ofNullable(T value)

    用这个啊

    如果你调用的 api 的编写人员不靠谱,那就让他别返回 Optional 了
    tamer
        15
    tamer  
       2021-01-25 15:41:30 +08:00
    @yuanxiaosong 这种例子其实很有误导性,
    实际业务代码往往并不会简单的是连续的方法引用
    LGA1150
        16
    LGA1150  
       2021-01-25 15:50:47 +08:00
    @huifer @11wangyaoda 这样写 IDE 会有警告
    arloor
        17
    arloor  
       2021-01-25 16:00:51 +08:00 via Android
    给你,你说鸡肋
    不给,你说缺失

    仔细看看自己写的代码,照样都是 trade off

    (点开看,原来不只是黑大 java,还要吹 rust,应该是最喜欢的编程语言评选又开始评选了
    xuanbg
        18
    xuanbg  
       2021-01-25 16:04:49 +08:00
    很少用,一般都是直接判空。某些场景在实体类的 get 方法中处理值为空。
    sakura1
        19
    sakura1  
       2021-01-25 16:06:16 +08:00
    这个问题感觉源自 null 的存在本身
    Takamine
        20
    Takamine  
       2021-01-25 16:07:00 +08:00 via Android
    建议可以看看《 Java 核心技术卷 2 》 Optional 的部分,比结合 flatMap 使用的。
    Takamine
        21
    Takamine  
       2021-01-25 16:09:07 +08:00 via Android
    比如*。

    我觉得这个是函数式编程新进来的,不能拆开来看。
    lemon94
        22
    lemon94  
       2021-01-25 16:18:31 +08:00
    swift 也有 optional,是繁琐了点,但解决 npe 问题还算有成效。
    hantsy
        23
    hantsy  
       2021-01-25 16:21:18 +08:00   ❤️ 3
    Optional 太常用了。

    思想固化,从来没用过 Java 8 的人才会去判断是不是 NULL,把好好的代码打回 Java 8 以前。

    Optional 在 Java 8 改进了很多,和 Stream 一样,用于 Pipeline 类似操作,很方便。

    https://github.com/hantsy/spring-webmvc-jwt-sample/blob/master/src/main/java/com/example/demo/DemoApplication.java#L34-L45

    ```java

    @Bean
    public AuditorAware<User> auditor() {
    return () -> Optional.ofNullable(SecurityContextHolder.getContext())
    .map(SecurityContext::getAuthentication)
    .filter(Authentication::isAuthenticated)
    .map(Authentication::getPrincipal)
    .map(User.class::cast);
    }
    ```

    再说了以 Spring 5 为基础,核心代码还有其 Spring 生态(比如 Spring Data ) API 都是对 Java 8 API 优化,Optional 在 Spring 中已经是随处可见,难道还没升级 Spring 5 ?
    assiadamo
        24
    assiadamo  
       2021-01-25 16:22:37 +08:00
    jdk 的 Optional 无法序列化且对 GC 有压力,有个好用的库叫 vavr 可以替代
    assiadamo
        25
    assiadamo  
       2021-01-25 16:23:21 +08:00   ❤️ 1
    比如 netty 就不用 Optional
    hantsy
        26
    hantsy  
       2021-01-25 16:27:03 +08:00
    如果用过 Spring WebFlux ( ReactiveStreams API )就更不用说了,流式操作是必须的。

    https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/main/java/com/example/demo/config/MongoConfig.java#L19-L28

    ```java
    @Bean
    ReactiveAuditorAware<Username> reactiveAuditorAware() {
    return () -> ReactiveSecurityContextHolder.getContext()
    .map(SecurityContext::getAuthentication)
    .filter(Authentication::isAuthenticated)
    .map(Authentication::getPrincipal)
    .map(UserDetails.class::cast)
    .map(UserDetails::getUsername)
    .map(Username::new)
    .switchIfEmpty(Mono.empty());
    }
    ```
    EscYezi
        27
    EscYezi  
       2021-01-25 16:29:53 +08:00 via iPhone
    @tamer #15 还得看实际业务,之前确实用到过这种写法
    Leviathann
        28
    Leviathann  
       2021-01-25 16:40:18 +08:00
    有时候把它当成三目用,至少比裸写三目漂亮
    chenfcheng
        29
    chenfcheng  
       2021-01-25 17:38:35 +08:00   ❤️ 2
    Optional.ofNullable(o1.getx().getxx().getXXX()).orElse() 这时候最有用 多层嵌套情况下 可直接设置默认值 多次判断是否为空
    mightofcode
        30
    mightofcode  
    OP
       2021-01-25 17:43:20 +08:00
    @yuanxiaosong 这就是我说的 stream 的场景
    mightofcode
        31
    mightofcode  
    OP
       2021-01-25 17:45:33 +08:00
    @Jooooooooo 不用 optional 抛出 NPE,用 optional,抛 NoSuchElementException

    optional 真的很鸡肋
    mightofcode
        32
    mightofcode  
    OP
       2021-01-25 17:46:37 +08:00
    @arloor

    给我,我说鸡肋
    不给,我说可以提供一个更好的
    zhuangzhuang1988
        33
    zhuangzhuang1988  
       2021-01-25 17:47:14 +08:00 via Android   ❤️ 1
    ✓ 很多 fp 就是放屁
    shyling
        34
    shyling  
       2021-01-25 17:47:28 +08:00
    黑 java 可以,但 rust 不是一样的操作?
    mightofcode
        35
    mightofcode  
    OP
       2021-01-25 17:50:11 +08:00
    @Jirajine optional 做不到强制检查 null,你一样可以选择直接调用 get,然后抛出 NoSuchElementException
    mightofcode
        36
    mightofcode  
    OP
       2021-01-25 17:50:55 +08:00
    @shyling rust 不一样,rust 如果声明不返回 null,那就绝对不会返回 null
    1011
        37
    1011  
       2021-01-25 17:51:53 +08:00
    @hantsy
    @yuanxiaosong

    fp 这个东西怎么说呢,实际写起业务来也需要设计一番,难度不比设计类、接口这些低
    如果自己设计、抽象的功底不够好还是简单 if else 走起吧,至少写出来的东西还能看懂
    mightofcode
        38
    mightofcode  
    OP
       2021-01-25 17:51:55 +08:00
    @LGA1150 警告不是 error,就有可能被无视
    mightofcode
        39
    mightofcode  
    OP
       2021-01-25 17:52:39 +08:00
    @sampeng optional 消灭不了空指针,你如果能用 optional 消灭空指针,发出来大家学习下
    yazinnnn
        40
    yazinnnn  
       2021-01-25 17:59:10 +08:00
    不过说实话,单拿 optional 出来做 fp 确实没啥用,java 的函数式还是太弱了
    LGA1150
        41
    LGA1150  
       2021-01-25 18:07:06 +08:00 via Android   ❤️ 1
    #31 如果你依赖 isPresent 和 get 方法,那就和传统的 != null 没区别
    真正有用的是 ifPresent, ifPresentOrElse, orElseGet 等的函数式方法
    shyling
        42
    shyling  
       2021-01-25 18:10:01 +08:00
    @mightofcode std::mem::transmute 有话说
    Jirajine
        43
    Jirajine  
       2021-01-25 18:14:21 +08:00 via Android
    @mightofcode 概念是一致的,给警告也算静态检查了,只要你不忽略警告,再就是它提供的那些 combinator 方法。
    kotlin 也分 nullable type,概念也是一样的,可能语法上好一点。
    hantsy
        44
    hantsy  
       2021-01-25 18:18:27 +08:00   ❤️ 2
    @yazinnnn 太弱?

    不,大约 5,6 年前,开始试用 Java8 的时候, 发现 Scala 没那么吸引人了。

    我在 Spring 项目中第一次大规模使用 Java 8 的 Function/Consumer/Supplier 是应用 Spring Integrations 4 的 Java 8 DSL,当时它是单独的模块,现在是 Spring Integration 5 核心的一部分了。

    https://spring.io/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
    hantsy
        45
    hantsy  
       2021-01-25 18:21:23 +08:00
    @1011 跟业务设计有毛线关系啊。

    代码换个写法而已,不喜欢依然可以传统的方式。
    otakustay
        46
    otakustay  
       2021-01-25 18:49:30 +08:00
    最根源的问题还是`null`是一个值而不是一个类型
    KarmaWu
        47
    KarmaWu  
       2021-01-25 18:56:31 +08:00
    Optional 判空还是挺香的,你可以不用,但是它存在即是合理
    mightofcode
        48
    mightofcode  
    OP
       2021-01-25 18:57:57 +08:00
    @KarmaWu 香在哪?既然合理,麻烦给一个合理分析
    nthin0
        49
    nthin0  
       2021-01-25 18:59:28 +08:00
    @chenfcheng 这样不行吧,得用.map(xx::getXXX),否则其中一个为 null 的时候还是会抛空指针
    bigbigeggs
        50
    bigbigeggs  
       2021-01-25 19:30:22 +08:00
    主要是强制吧,和自己 xx == null 来进行判断。
    直接抛异常,他不香么
    ilumer
        51
    ilumer  
       2021-01-25 19:38:24 +08:00
    Vedar
        52
    Vedar  
       2021-01-25 19:42:31 +08:00
    确实挺蛋疼的 主要还是因为不是 zero cost 的 所以还是很少用 除了一些必须要用的地方比如和 stream 交互的地方
    Vedar
        53
    Vedar  
       2021-01-25 19:48:45 +08:00
    另外 java 自带的 optional 不支持序列化 有时候也挺烦的
    taojintianxia
        54
    taojintianxia  
       2021-01-25 19:49:39 +08:00
    就是因为大量人员不做判空导致大家都在写防御性代码。第三方或者前端的数据我们无法保证一定非空,但是内部接口调用,我们难道无法保证参数是否为空吗。
    LGA1150
        55
    LGA1150  
       2021-01-25 19:50:31 +08:00
    @Vedar #52 JIT 会优化的
    young1lin
        56
    young1lin  
       2021-01-25 19:57:06 +08:00
    怎么缩呢,这个其实有点用。Spring 源码就用到了这个,在 DefaultListableBeanFactory 这个类里面好像。可以进行流式判断,确实能省好多代码,就是没仔细学过 Java8 的容易懵逼。
    Vedar
        57
    Vedar  
       2021-01-25 19:58:13 +08:00
    @LGA1150 这怎么优化? jit 会将热点代码编译成机器码来提高速度 但是内存的申请和释放还是一样的呀,optional 包了一层对象 增加了 gc 压力 这不是一定的么
    cigarzh
        58
    cigarzh  
       2021-01-25 20:01:28 +08:00
    > 给你,你说鸡肋
    > 不给,你说缺失
    我觉得还挺有道理的,不过我也反对降低代码可读性来做防御式编程
    Aimers
        59
    Aimers  
       2021-01-25 20:04:32 +08:00
    kt 大法好
    blackboom
        60
    blackboom  
       2021-01-25 20:09:55 +08:00 via Android
    个人感觉 Optional 非常普遍啊?🤔🤔 如果使用 Spring boot 的话,随便找一找都是 Optional 的影子。

    如果某个接口返回 Optional 说明调用方需要判空,返回一定有值为什么要使用 Optional API ?

    在 Java 中 Optional 绝对不是鸡肋,并且很好用。
    LGA1150
        61
    LGA1150  
       2021-01-25 20:17:30 +08:00
    @Vedar #57 new 操作也是可以被优化掉的,有个 JVM 开关是 EliminateAllocations (标量替换),默认打开的
    namelosw
        62
    namelosw  
       2021-01-25 20:21:54 +08:00
    Java 的 Optional 和 Rust 的区别不大, 可读性下降是因为缺对应的 monadic 语法糖 . 能把?.之类的语法变换成 map 和 flatMap. 这个 Java 想加也能加, 其实就是 Scala 的 for 语法.

    Rust 和 Java 不兼容的地方是 borrow checker, 但是和你说的这个问题没有关系.

    同理还有 Stream / Future 之类的和 async await 的关系.
    hantsy
        63
    hantsy  
       2021-01-25 20:35:12 +08:00
    @cigarzh 可读性很多时候是个人问题习惯而已。Scala 的语法可读性好吗?不照样有一群忠实粉丝。

    Optional/Stream/Function/Labmda,Future 等,正经项目用过一次就习惯了,你再也不想回去了。

    至于讨论“XXX 是鸡肋”这个问题本身就是鸡肋。

    如果对于一种语言新语法,讨论如果使用,与其他语言对应的语法缺少什么,有什么优点,那还算一个帖子有点正面意义。

    国内所有论坛的帖子,最多的就是在一些扯蛋的问题上撕逼。
    fpure
        64
    fpure  
       2021-01-25 20:38:58 +08:00
    Java 的 Optional 最大的问题是即使有 Optional,你依然必须给对象判 null,因为 Java 允许空指针就已经给类型系统打了一个洞了,这时候是否使用 Optional 就意义不大了,确实算鸡肋
    sampeng
        65
    sampeng  
       2021-01-25 20:47:02 +08:00 via iPhone
    @mightofcode 你这就属于抬杠了,上下文意思是空指针异常啊…
    sampeng
        66
    sampeng  
       2021-01-25 20:52:09 +08:00 via iPhone
    @mightofcode 再说了,你认为警告没用,那是你们代码没有 review,没有静态代码检查,没有很多强制性的要求。放飞自我随便写那确实没啥区别。对于很多开发而言,在学习语言编程的一节课或者说被教育的第一件事:不要忽略警告提示。

    编码调试阶段只有两个信息,错和没错。没有中间那档。
    Vedar
        67
    Vedar  
       2021-01-25 21:13:56 +08:00
    @LGA1150 受教了 jit 还有这个功能 才知道 看了下 这个只能替换没有逃逸的对象吧,实际上 optiona 大多 l 作为函数返回值,还是优化不了的
    AItsuki
        68
    AItsuki  
       2021-01-25 21:32:23 +08:00
    还行吧,optional 通过链式调用的时候是能提升阅读性的,例如 a.b().c().d()任何一环都有可能是空的情况。这种时候使用 optional 就很优雅。其他就见仁见智了。
    Kaiv2
        69
    Kaiv2  
       2021-01-25 22:16:21 +08:00
    @AItsuki
    Optional.ofNullable(a)
    .map(type::b)
    .map(type::c)
    .map(type::d)
    .orElse((type)null);

    Optional 个人感觉很好用,刚开始可能不习惯,思维模式转变后发现真香
    Kaiv2
        70
    Kaiv2  
       2021-01-25 22:23:18 +08:00
    @Kaiv2 这个例子看看不用 Optional 需要几次手动判空
    lululau
        71
    lululau  
       2021-01-25 22:25:21 +08:00
    还有人说 Stream API 比 for (int i=0; i <n; i++) 可读性低呢
    casillasyi
        72
    casillasyi  
       2021-01-25 23:04:19 +08:00
    v 站人均 jdk 开发者水平了吗?难读了,你这个结论是来自你自己的感觉还是有数据支撑?
    WispZhan
        73
    WispZhan  
       2021-01-25 23:06:08 +08:00
    Optional 设计初衷是给 Lambda 和 Stream 用的,并不是单纯给你来判空与否的。
    casillasyi
        74
    casillasyi  
       2021-01-25 23:08:42 +08:00
    “如果真这么好用,那么入参也应该用用起来啊。” 这前后有因果关系吗?你认真看过原作者的建议吗?

    “但是这个只是警告,是非强制的。” 我就非要用 new 一个空对象出来,然后让他在某个地方空指针,反正编译过了就行。是不是一个意思?

    你这样的心态,建议不要写 Java 了,去写某一个什么都给你安排的好好的语言。
    LGA1150
        75
    LGA1150  
       2021-01-25 23:36:43 +08:00
    @Vedar JIT 也会内联方法的,内联了就可以做优化
    no1xsyzy
        76
    no1xsyzy  
       2021-01-26 00:24:56 +08:00
    同理 Checked exceptions 也一样,Python 不也能正常错误处理吗?
    但为什么还是推荐 Checked exceptions 呢?
    这是协作的问题,不是业务逻辑的问题
    但是,缺乏语法糖也是一个问题。

    另外,入参的问题,Optional 是协变的,所以不会用于入参……
    siweipancc
        77
    siweipancc  
       2021-01-26 09:10:40 +08:00 via iPhone
    舌战群儒:D
    passerbytiny
        78
    passerbytiny  
       2021-01-26 09:15:37 +08:00 via Android
    不想用 Stream 方式写代码,别说自己会 Java8 。

    自己没见过就说没用,别说自己会 Java 。
    cheng6563
        79
    cheng6563  
       2021-01-26 09:25:23 +08:00
    Java 缺的是个 Notnull 标记而不是 Nullable 标记,这里看 Optional 挺鸡肋的,更不用说 Optional 自己还可能为 null
    masterclock
        80
    masterclock  
       2021-01-26 09:58:57 +08:00
    在返回要求 Optional 的函数里返回 null 的程序员是不是应该开除?
    PiersSoCool
        81
    PiersSoCool  
       2021-01-26 10:25:38 +08:00
    如 a.b.c.d.e.f 的时候喜欢用 Optional
    要是 a 我喜欢用 null == a
    怎么方便怎么来
    CosimoZi
        82
    CosimoZi  
       2021-01-26 10:31:30 +08:00
    球球你们学点 plt 吧
    qiyuey
        83
    qiyuey  
       2021-01-26 10:59:52 +08:00
    不如 Kotlin 彻底一些
    casillasyi
        84
    casillasyi  
       2021-01-26 11:00:20 +08:00
    @cheng6563 能让 optional 为 null 的,跟写 if (true) 也没区别
    unco020511
        85
    unco020511  
       2021-01-26 11:16:59 +08:00
    kotlin 的好用
    yl666
        86
    yl666  
       2021-01-26 11:32:01 +08:00
    我有个 String 类型的数据,本来想通过用 Optional.ofNullable 来判断是否为空的,结果看了下源码发现它是用 xx == null 来判断的,最后还是用 if 判断吧,其实 Optional 挺好用的,只不过某些场景不太适合
    zhuangzhuang1988
        87
    zhuangzhuang1988  
       2021-01-26 11:35:58 +08:00
    @lululau 可读性确实低
    而且性能差, 而且可调试不好
    hantsy
        88
    hantsy  
       2021-01-26 11:53:15 +08:00
    @casillasyi 写法差别很大。
    Optional 流式操作都是假定它不是 Null,如果数据流遇到 Null 的情况走 Else 路线,这和 Scala 中 OPTION,SOME,NULL 类似,Java 8 中要处理 if a= null 情况使用 Optinal 非常容易,代码看起来舒服得多, 在实际项目非常实用。

    下面 Spring 5.2 加入 MVC 加入 Funtional 编程的例子,传统的 Controller 一样可以用。

    https://github.com/hantsy/spring-webmvc-functional-sample/blob/master/java/src/main/java/com/example/demo/DemoApplication.java#L77-L85

    ```java
    public ServerResponse get(ServerRequest req) {
    return this.posts.findById(Long.valueOf(req.pathVariable("id")))
    .map(post -> ok().body(post))
    .orElse(notFound().build());
    }
    ```
    hantsy
        89
    hantsy  
       2021-01-26 11:55:54 +08:00
    @yl666 所有的判断 Null 的情况都是可以用 Optional, 更方便。 你觉得不方便或者不适合,只是思想上还没接受 Stream 方式,缺少 Stream API 使用实践。
    casillasyi
        90
    casillasyi  
       2021-01-26 11:58:59 +08:00
    @hantsy 我觉得他们认为的 optional 本身是 null 的情况是这个对象是 null,而不是 value 为 null
    AxEqaq
        91
    AxEqaq  
       2021-01-26 12:15:10 +08:00
    用 guava 的 cache 还是需要用到 optional 判空的
    hantsy
        92
    hantsy  
       2021-01-26 12:19:25 +08:00
    @casillasyi

    API 设计本来就应该一层层约束的,如果调用别从的 API,返回 Optional,成为规约,而不应该返回是 Null 。

    再说了,Spring 5 内部强制大量使用了 Asserts 工具类, Bean Validation (输入参数)和 JSR 305 (输入,结果等都可以约束) 来保证 API 稳定性。Spring Data 中 findByID 很早就改成返回 Optional, 用了几年,从来没见过返回此处 Optional==Null 的情况。如果有,请帖一些公开的开源的 API 看看。
    casillasyi
        93
    casillasyi  
       2021-01-26 12:30:43 +08:00
    @hantsy 问他们啊。。。
    oneisall8955
        94
    oneisall8955  
       2021-01-26 12:33:42 +08:00 via Android
    一开始我觉得鸡肋,后来发现是自己姿势不对(=_=)
    oneisall8955
        95
    oneisall8955  
       2021-01-26 12:41:47 +08:00 via Android
    @huifer 接口定义返回 Optional,默认就是不会返回 null,调用者不用判断是否是 null,如果返回 null,把锅甩给开发这个接口的辣鸡开发
    oneisall8955
        96
    oneisall8955  
       2021-01-26 12:43:45 +08:00 via Android
    @hantsy 赞同,楼上说需要 optional == null 都是没理解透彻 optional 的精髓
    hantsy
        97
    hantsy  
       2021-01-26 13:14:56 +08:00
    @oneisall8955 这个情况在国内可能太多了,因为之前我在上海两个创业项目的经历,现在的年轻开发人员基本敷衍做事的太多,很多基本的代码约束都做不到,要费很多唇舌去要求。

    不知道国内有多少用过 Null Object 模式。但我觉得这应该是一个最基本的问题,可以回避很多 Null 代码检测问题。

    另外,像 Collection 类的使用,从我开始工作时,就看到一些相关的模式(或者叫实践)使用,比如:一个类中有一个 Collection field,应该初始化为一个 EmptyList/Set 等,有方法返回 Collection,永远保证不会返回 Null (没有结果以 Empty List/Set 代替)。
    nnnToTnnn
        98
    nnnToTnnn  
       2021-01-26 13:18:06 +08:00
    Java 基本上好几年没写了,我的 jdk 8 出来的时候, 我依稀记得 optional 是为了解决 a?.b() 的问题,但是由于 Java 是面向对象的语言,这个思想还没怎么转换过来。 所以目前的 optional 应该是为了解决 Stream API 中 a?.b() 的问题,而不是单纯的空指针。
    nnnToTnnn
        99
    nnnToTnnn  
       2021-01-26 13:20:56 +08:00
    例子 这是一个 List 结构
    ```
    {
    user: {
    name: {
    name: {
    name: {
    key: '1'
    }
    }
    }
    }

    }

    ```

    以上每一个字段都有可能是空,那么你会先 5 个 if 语句来进行判断,optional 估计是解决这个问题的。
    jewer3330
        100
    jewer3330  
       2021-01-26 13:31:54 +08:00
    吃瓜群众
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5879 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 02:17 · PVG 10:17 · LAX 19:17 · JFK 22:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.