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

吐槽 Java 8 的 Optional

  •  
  •   acr0ss · 2017-09-30 10:00:31 +08:00 · 7309 次点击
    这是一个创建于 2611 天前的主题,其中的信息可能已经有所发展或是发生改变。

    官方说是用于防止空指针的。
    1.如果类的某个字段是 Optional,那就意味着 Nullable,会强制做 isPresent()判断是否为空
    2.如果方法返回类型是 Optional,那就意味着 Nullable,也需要做 isPresent()判断是否为空

    实际使用中,感觉对原有的返回类型,字段类型改动很大,所以没咋用。

    同事却把这个 Optional 当成了炫技的手段。

    一个为空的判断,只要 object == null 就可以;
    同事却一直使用

    !Optional.ofNullable(object).isPresent()  
    

    同理非空判断是

    Optional.ofNullable(object).isPresent()
    

    哎呦我去,这个绕。

    ---吐槽します---

    第 1 条附言  ·  2017-09-30 16:47:18 +08:00
    2017 年 9 月 30 日 16:46
    我这里只是吐槽被同事滥用,没说这个特性不好。
    有人 get 到了,有人没有。
    第 2 条附言  ·  2017-09-30 17:01:58 +08:00
    2017 年 09 月 30 日 16:57
    移步 10、11 楼,给大佬递茶
    32 条回复    2017-10-07 11:43:13 +08:00
    6IbA2bj5ip3tK49j
        1
    6IbA2bj5ip3tK49j  
       2017-09-30 10:05:41 +08:00
    一个不做判断 null,IDE 会提示。
    一个不做没有任何影响。
    区别在这儿吧。



    kotlin 解决这个问题更优雅。
    gongzhang
        2
    gongzhang  
       2017-09-30 10:07:44 +08:00   ❤️ 1
    😂optional 理念没问题,但死活不改 java 语法就只好这样了。。。
    我还是觉得 @Nullable 和 @NotNull 更容易有效运用😂
    acr0ss
        3
    acr0ss  
    OP
       2017-09-30 10:09:52 +08:00
    @xgfan 问题是,非空判断不至于整的这么复杂吧。现在 IDEA 很只能,不做判断会提示可能空指针的。
    gcli
        4
    gcli  
       2017-09-30 10:11:47 +08:00   ❤️ 2
    microhz
        5
    microhz  
       2017-09-30 10:12:27 +08:00
    连续做非空判断还是有简介的,可以减少 if 嵌套
    QAPTEAWH
        6
    QAPTEAWH  
       2017-09-30 10:16:28 +08:00
    - Optional 是代替空指针的,该空的东西还是会空
    - Optional 只能避免反复的 if (xxx != null), 不能避免 NullPointerException
    - 正确用法是多用 .map, .orElse, 如果你处处在用.isPresent, 还不如用老办法
    QAPTEAWH
        7
    QAPTEAWH  
       2017-09-30 10:19:57 +08:00
    - 空指针是“在类型系统上开了个洞”
    kenken
        8
    kenken  
       2017-09-30 10:22:05 +08:00 via iPhone
    map filter ifpresent orelse
    huangchang250
        9
    huangchang250  
       2017-09-30 10:25:00 +08:00
    应该吐槽的是你的同事
    BoiledEgg
        10
    BoiledEgg  
       2017-09-30 10:25:35 +08:00   ❤️ 1
    你同事滥用的问题
    let xxx = {
    "a": {
    "b": {
    "c": "content"
    }
    }
    }

    你要获取 c 的值, 如果只是获取值,看起来不用 Optional 还少些代码
    return xxx!=null && xxx.a!=null && xxx.a.b!=null && xxx.a.b.c!=null?xxx.a.b.c: defaultC;
    return Optional.ofNullable(xxx).map(xxx -> xxx.a).map(a -> a.b).map(b -> b.c).orElse(defaultC);
    但是一旦要获取 a,b 后做计算,修改再获取 C 的值,不用 Optional 就只能 if else 嵌套再嵌套了。

    事实上,Java 有 Optional,Javascript 也有个类似的库叫 data.maybe,里头也是 fromNullable 这套,毕竟链式调用看上去比 if else 嵌套要舒服。
    chocotan
        11
    chocotan  
       2017-09-30 10:33:02 +08:00   ❤️ 6
    楼上们说的挺清楚了,我贴个书上的简单的栗子

    mgcnrx11
        12
    mgcnrx11  
       2017-09-30 10:59:37 +08:00   ❤️ 1
    zhx1991
        13
    zhx1991  
       2017-09-30 11:00:07 +08:00
    object == null 的判断会被忘记
    0915240
        14
    0915240  
       2017-09-30 11:16:40 +08:00 via iPhone
    就是提醒处理 null 算是一种约束吧。


    之前 guava 里面好像也是这么解释的。


    另 orelse 之类针对 if null then default value 蛮好的。
    incompatible
        15
    incompatible  
       2017-09-30 11:27:53 +08:00
    “实际使用中,感觉对原有的返回类型,字段类型改动很大,所以没咋用。"
    这就是你的问题了。

    如果你肯把方法的返回值写成 Optional,那么你同事也不用费劲地写 Optional.ofNullable()了
    svenFeng
        16
    svenFeng  
       2017-09-30 11:41:24 +08:00 via Android
    这东西得有模式匹配才能发挥真正的作用,直接在编译器杜绝空指针,参见 rust/haskell,而 Java 的话,这东西当作要判断空指针的标识就可以了
    lihongjie0209
        17
    lihongjie0209  
       2017-09-30 11:45:51 +08:00
    map 或者是 ifPresent, 上面这种用法是官方不推荐的, 因为这么用和用 null 没区别
    lihongjie0209
        18
    lihongjie0209  
       2017-09-30 11:46:56 +08:00   ❤️ 4
    具体内容可以看这个:
    &t=25s
    hantsy
        19
    hantsy  
       2017-09-30 11:49:07 +08:00
    @chocotan 这个正解。
    没用过 Stream 的人很难理解 Optional,现在满世界都是 Steam/ Pipeline 了。

    @acr0ss 照你这么说 Reactive Streams 设计全部是鸡肋了, Reactor/RxJava 是脱裤子放屁? Spring 5 的最大的特性就是引入全套 Reactive 支持,https://github.com/hantsy/spring-reactive-sample
    lcgui7
        20
    lcgui7  
       2017-09-30 11:51:16 +08:00
    @chocotan 这什么书?下面这个例子编译不通过吧。
    teek
        21
    teek  
       2017-09-30 14:13:12 +08:00
    honeycomb
        22
    honeycomb  
       2017-09-30 14:19:27 +08:00
    仅仅是单个用 Optional.isPresent,确实如楼主所说没意思。

    比较合适的用法是
    @chocotan @hantsy

    类似的:
    吐槽します --> ツッコミします 会比较合适,前者就有些像单用 Optional.isPresent 了,吐槽密达同理。
    pynix
        23
    pynix  
       2017-09-30 14:27:03 +08:00
    哈哈哈
    acr0ss
        24
    acr0ss  
    OP
       2017-09-30 16:40:32 +08:00
    @BoiledEgg 学到了 谢谢
    acr0ss
        25
    acr0ss  
    OP
       2017-09-30 16:40:55 +08:00
    @honeycomb 哈啊哈
    不用在意这个
    acr0ss
        26
    acr0ss  
    OP
       2017-09-30 16:42:19 +08:00
    @huangchang250 you got it
    acr0ss
        27
    acr0ss  
    OP
       2017-09-30 16:44:10 +08:00
    @hantsy 大胸弟,我没说不用 stream 好吧。 你这随便喷的口气改一改,谢谢!
    misaka19000
        28
    misaka19000  
       2017-09-30 16:45:33 +08:00 via Android
    不应该用 shi mashida 嘛。。。
    acr0ss
        29
    acr0ss  
    OP
       2017-09-30 16:51:01 +08:00
    @misaka19000 给各位日语大佬递茶
    crash
        30
    crash  
       2017-09-30 18:17:27 +08:00
    用过 swift 的表示,optional 没楼上那么复杂。使用 optional 并不需要知道 RX 系列。
    hantsy
        31
    hantsy  
       2017-10-01 12:04:12 +08:00
    @acr0ss 常常忍不住一些看法,谅解。

    RxJava `Maybe` 和 Reactor `Mono` 才是 Optional 想要变成的样子,只是 Java Optional 生的太早。Java 9 Flow API 直接 Copy 了 ReactiveSteams JVM 的 API,提供了一个简单的实现。
    troywinter
        32
    troywinter  
       2017-10-07 11:43:13 +08:00
    从 optional 扯到 stream 和 rx 也是醉了,你们要不要继续扯扯 monad。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   913 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:42 · PVG 05:42 · LAX 13:42 · JFK 16:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.