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

被怼的莫名奇妙的,这么写会出空指针?

  •  
  •   cxsz · 2022-03-19 13:10:31 +08:00 · 3714 次点击
    这是一个创建于 985 天前的主题,其中的信息可能已经有所发展或是发生改变。
    这个我怎么想都觉得不可能出空指针,那不这么写有啥好方法




    说 java 代码中“.”的使用不要 xx.xx.xx 这种写法,但这个地方用 stream 难道不是最好的写法
    24 条回复    2022-04-29 08:12:11 +08:00
    ikas
        1
    ikas  
       2022-03-19 13:18:46 +08:00   ❤️ 2
    如果真的非要说空指针,这里问题不是 xx.xx.xx 写法
    而是,你的 list 包含可能为 null 的 item,然后 getStationId 有可能返回 null,然后再次返回包含 null 的 list
    LxExExl
        2
    LxExExl  
       2022-03-19 13:19:56 +08:00 via iPhone
    mylist?.getFirst()?.getAttribute()?.toString()

    有语法糖的语言可以这样

    java 楼主的截图确实会有空指针问题吧
    那么怎么解决。一路嵌套 if 还是 catch 住异常?
    9c04C5dO01Sw5DNL
        3
    9c04C5dO01Sw5DNL  
       2022-03-19 13:27:10 +08:00   ❤️ 2
    stationId 如果事实不可能为空的话,你让他给你造一个 null 出来试试。

    可能为空的话就 filter 一下完事。

    另外,判断 list 是否 empty 有点多余了(前提 list 不为 null )
    cxsz
        4
    cxsz  
    OP
       2022-03-19 13:28:01 +08:00
    @ikas #1 这个确实可能会存在,返回的 list 在操作前也有判空处理,但就单独这行来说,我觉得用 stream 语法糖没啥问题,用循环加判断,一样会存在同样的问题
    kisick
        5
    kisick  
       2022-03-19 13:38:51 +08:00   ❤️ 2
    userStationList.add(null);
    这样是有可能空指针的,加个.filter(Objects::nonNull)就好了
    cxsz
        6
    cxsz  
    OP
       2022-03-19 13:42:26 +08:00
    @giiiiiithub #3
    @kisick #5

    好的,感谢
    Hurriance
        7
    Hurriance  
       2022-03-19 13:43:22 +08:00
    应该是 stream().map(null) 这个会 NPE 吧,最近有遇到过
    maojun
        8
    maojun  
       2022-03-19 13:48:49 +08:00 via iPhone
    你列表里的元素如果有 null 的话,调用 getStationId 不就空指针了
    TWorldIsNButThis
        9
    TWorldIsNButThis  
       2022-03-19 14:09:27 +08:00 via iPhone
    可以包一层 optional
    wolfie
        10
    wolfie  
       2022-03-19 14:09:49 +08:00
    userStationList 为什么会包含空?
    cxsz
        11
    cxsz  
    OP
       2022-03-19 14:20:00 +08:00
    @wolfie #10 因为 server 层没拿到数据是会返一个空的
    Suddoo
        12
    Suddoo  
       2022-03-19 15:20:28 +08:00
    集合里的对象全为 null ,遍历集合里每个对象取其中的属性,空指针出现了
    q1angch0u
        13
    q1angch0u  
       2022-03-19 15:25:23 +08:00 via iPhone
    optional 啊…
    cryboy007
        14
    cryboy007  
       2022-03-19 16:02:03 +08:00
    请先 filter 过滤在 map
    night98
        15
    night98  
       2022-03-19 17:48:48 +08:00
    楼主写的没问题,这个 list 一看就知道是从数据库拿的,也判空 list 了,如果 list 里面还有元素能为空的话,先把数据提供方拉出去打一顿吧。
    wolfie
        16
    wolfie  
       2022-03-19 17:49:06 +08:00
    @cxsz
    为什么 service 的查询返回 List 会存在 null 。
    stream map to IdList 一点问题没有,List 里硬赛一个 null 才是问题。
    daimubai
        17
    daimubai  
       2022-03-19 23:59:33 +08:00
    @ikas 如果有包含为 null 的 item, 在 getStationId 时就已经抛出 NPE 了。 你说的应该是如果有 item 的 stationId 是 null ,才会返回包含 null 的 list
    ikas
        18
    ikas  
       2022-03-20 00:17:10 +08:00
    @daimubai ,对,我说的是 2 种,第一种就是 npe 了,然后第二种可能给后续的代码留坑
    ikas
        19
    ikas  
       2022-03-20 00:21:26 +08:00   ❤️ 2
    @cxsz 对的..主要原因是..List 这种结构我们无法判定是否包含 null,本身使用 stream 这种用法没有任何问题,如果别人拿这个说事情其实就是老顽固而已..

    如同其他的回答一样,使用保守写法,加上 filter,然后 getid 里也根据业务加上是否需要剔除 null

    其实这里问题就好多了...
    返回 list 是否可能 null
    如果 getid 如果为 null,是要抛出异常,还是要剔除,这些都是要根据业务的
    ubuntuGary
        20
    ubuntuGary  
       2022-03-20 22:39:53 +08:00   ❤️ 1
    如果被怼是理由是你用 Stream 流式的写法,就很没有道理了,list 里有 null 元素,你换成外部迭代写法也一样有可能 NPE ,而如果被怼的原因就是你没考虑 null 元素,那你只能认,不能说 Stream 流式写法不好,Stream 流加个 filter 也就解决了,不过相比你这个问题,上游的 list 里有 null 元素更加不可原谅。
    chainsR
        21
    chainsR  
       2022-03-21 09:19:51 +08:00 via iPhone
    要过滤的,不要相信数据
    rehoni
        22
    rehoni  
       2022-04-27 16:52:55 +08:00
    肯定不是 stream 的问题,就算你 foreach 也会 npe 的,最好确保数据可靠性,给你找了个写法
    [如果整个 list 可能为 null] 用 Optional 包装一下
    [如果 list 中的某个 object 可能为 null] 用 .filter(Objects::nonNull)

    List<Person> personList = new ArrayList<>();
    personList.add(new Person());
    personList.add(null);
    personList.add(new Person("小明", 10));
    personList.add(new Person("小红", 12));

    Optional.ofNullable(personList).orElseGet(() -> {
    System.out.println("personList 为 null !");
    return new ArrayList<>();
    }).stream().filter(Objects::nonNull).forEach(person -> {
    System.out.println(person.getName());
    System.out.println(person.getAge());
    });
    cxsz
        23
    cxsz  
    OP
       2022-04-28 15:24:47 +08:00
    @rehoni #22 好的,谢谢。 已经一个月过去了这个帖子是怎么被翻出来的。。。。
    rehoni
        24
    rehoni  
       2022-04-29 08:12:11 +08:00
    @cxsz 。。。感觉 java 话题下排的很靠前哇。。可能这话题没多少人发帖子吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5394 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:56 · PVG 13:56 · LAX 21:56 · JFK 00:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.