Java Stream的map转换中属性可能为null却被判定为非null的编译警告问题
嗨,我来帮你拆解这个问题的原因,顺便先指出几个明显的小问题!
首先,先看你的Clazz类——你给someAttribute加了final修饰符,但又写了setSomeAttribute方法试图修改它,这在Java里是根本编译不通过的哦!final变量只能在声明时或者构造方法里赋值,之后无法被修改,这大概率是你写代码时的笔误,建议先把这个问题修正,不然后面的代码都没法正常运行。
接下来回到你遇到的编译警告问题,核心原因是**Optional.map方法的特性**:
- 当
Optional中的值为null时,map会直接返回一个空的Optional,不会执行传入的lambda表达式; - 只有当
Optional中的值非null时,才会调用lambda处理这个值。
看你这段代码:
Optional.ofNullable(someObject) .map(Clazz::getSomeAttribute) .map(someAttribute -> Objects.notNull(someAttribute)) // 这里的someAttribute一定是非null的! .map(result -> result ? "string1" : "string2") .orElse("");
第二个map的lambda参数someAttribute,只有在前一个map(也就是Clazz::getSomeAttribute)返回非null值的时候才会被执行。编译器能识别到这一点,所以它知道someAttribute不可能为null,那Objects.notNull(someAttribute)的结果就永远是true,自然会警告你这个判断是多余的。
那怎么实现你想要的逻辑呢?其实你不需要手动判断someAttribute是否为null,利用Optional的特性就能搞定:
如果你想实现的是「如果someObject存在且someAttribute非null,返回string1,否则返回string2(或空)」,可以这样写:
Optional.ofNullable(someObject) .map(Clazz::getSomeAttribute) // 当属性非null时映射为string1,否则进入orElse .map(attr -> "string1") .orElse("string2");
如果逻辑更复杂,需要先过滤掉null属性,可以用filter:
Optional.ofNullable(someObject) .map(Clazz::getSomeAttribute) .filter(Objects::nonNull) .map(attr -> "string1") .orElse("string2");
最后还要提一下你代码里的两个小笔误:new Clasz()应该是new Clazz(),还有字符串用了中文引号“”,要改成英文的""哦!
备注:内容来源于stack exchange,提问作者Sandeep Barnabas

