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

JAVA8 的 Optional 是鸡肋

  •  
  •   mightofcode 2021-01-25 15:00:29 +08:00 14035 次点击
    这是一个创建于 1720 天前的主题,其中的信息可能已经有所发展或是发生改变。
    对于处理 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 问他们啊。。。
    itechify
        94
    itechify  
    PRO
       2021-01-26 12:33:42 +08:00 via Android
    一开始我觉得鸡肋,后来发现是自己姿势不对(=_=)
    itechify
        95
    itechify  
    PRO
       2021-01-26 12:41:47 +08:00 via Android
    @huifer 接口定义返回 Optional,默认就是不会返回 null,调用者不用判断是否是 null,如果返回 null,把锅甩给开发这个接口的辣鸡开发
    itechify
        96
    itechify  
    PRO
       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     Solana     2686 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 14:08 PVG 22:08 LAX 07:08 JFK 10:08
    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