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

吐槽 Java 8 的 Optional

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

    官方说是用于防止空指针的。
    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()了
    Em5O7B1JGfjQnBry
        16
    Em5O7B1JGfjQnBry  
       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     Solana     4665 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 01:04 PVG 09:04 LAX 18:04 JFK 21:04
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86