1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

记一次线上环境空指针异常排查

前言

现在,很多小伙伴都在日常开发中使用lambda表达式,我也经常用,我们线上环境的代码更是广泛使用,而且我之前还给大家分享过一些常用的lambda表达式,因为lambda确实很好用,用起来也确实很方便,但是各位小伙伴在使用过程中一定要做好数据校验,避免线上环境出现出现空指针异常,今天我们就来分享下我这一天排查线上环境发现的一个空指针异常(NPE),这个问题确确实实是那种你不遇到,你根本不知道的异常。话不多说,我们直接开始吧。

问题分析

我们先看这样一段代码:

public static void main(String[] args) {
        TestVo testVo = new TestVo();
        List<TestVo> testVoList = Lists.newArrayList(testVo);
        Map<String, Integer> collectMap = testVoList.stream().collect(Collectors.toMap(TestVo::getName, TestVo::getAge));
        System.out.println(collectMap);
    }

这段代码没有什么复杂的业务逻辑,咋看没有任何问题,我当初也是这么想的,但是经过我的实际测试,以上代码有两处潜在的空指针异常。

第一处大家应该都可以看出来,就是testVoList为空的时候,所以在日常开发i中,如果是从数据库查出来的list,一定要做空指针判断;

另一处我开始也没看出来,直到我做了很多次测试以后,才发现这个隐藏的NPE。我们先说结论,toMap方法如果后一个参数(即TestVo::getAge,对应我们map的值)为空,整个lambda就会报空指针异常:

详细分析异常,你会发现,toMap方法在执行过程中会调用merge方法,merge方法要求value不能为空:

所以各位小伙伴在以后的开发中一定要尽可能避免这两种空指针异常的出现,对于第二种空指针可以通过下面这种方式避免:

Map<String, Integer> collectMap = testVoList.stream().collect(Collectors.toMap(TestVo::getName,
                t -> {
                    if (t.getAge() == null) {
                        return 0;
                    } else {
                        return t.getAge();
                    }
                }));

对于上面的代码,如果把age的类型改成int,就不会报错,因为基本类型int的初始化是0。所以,这里其实还隐含了第三种空指针异常,包装类转基本类型的空指针异常。

如果你的代码中有,包装类转成基本类型的情况,请务必做好空指针判断,否则也是会有空指针异常的,比如像像下面这段代码:

Integer a = null;
int b = a;

直接运行,就是空指针异常:

所以,各位小伙伴在使用基本类型与包装类的时候,一定要尽可能保持类型一致,如果用包装类就都用包装类,非要做转换的话,就务必做好数据校验。另外,由于基本类型和包装类对java来说是两种类型,所以下面的方法对java来说是两个方法,也就是我们说的重载:

private void testInt(Integer i) {
    System.out.println(i + i);
}

private void testInt(int i) {
    System.out.println(i * i);
}

但这种重载对调用方来说是极其不友好的,我在我们线上环境还真的遇到过,调用哪个方法取决你传的是基本类型还是包装类(谁在实际开发中会关注这个?),所以各位小伙伴一定要避免类似这种方法重载,这种代码一旦出现问题,那就真的把你往死里坑。

总结

作为一个后端开发人员,减少NPE错误是我们最基本的追求,所以各位小伙伴在实际开发过程中一定要尽可能避免,因为一旦发生NPE异常,不仅对用户交互不够友好,排查问题也不方便,而且从个人角度来说,不论你能力有多强,贡献有多大,如果你开发的一个核心功能因为没有做数据校验,最后导致NPE异常,影响系统正常运行,那你怕要背上一个p1甚至p0工单,搞不好还会被开除,这样你不觉得冤吗?总之就是,日常开发过程中要尽一切可能避免NPE异常,不犯这种低级错误,你的职场发展才能走的更顺利。

posted @ 2021-07-15 13:35  云中志  阅读(257)  评论(0编辑  收藏  举报