为什么在以下Java Stream过滤器方法中不抛出NullPointerException

时间:2017-05-29 18:41:14

标签: java java-8 java-stream

Blankie的第二个对象的颜色值为null,当它通过流管道时,它在null上检查equals()但是不会抛出NullPointerException。为什么会这样?

打包神话;

import java.util.stream.Stream;

class Blankie {
    String color = null;

    boolean isPink() {
        return "pink".equals(color);
    }
}

public class PreSchool {
    public static void main(String[] args) {
        Blankie b1 = new Blankie();
        Blankie b2 = new Blankie();
        b1.color = "pink";
        // String a1 = null;
        // System.out.println(a1.equals("ad"));
        Stream.of(b1, b2).peek(a -> {
            System.out.print(a.color);
        }).filter(Blankie::isPink).forEach(System.out::println);
    }
}

4 个答案:

答案 0 :(得分:4)

没有理由抛出NullPointerExceptionequals()的{​​{1}}方法将接受String的参数并返回null。对于两个字符串值falses1,如果s2s1.equals(s2),则表达式NullPointerException只会抛出s1。在您的代码中,null是字符串常量s1

答案 1 :(得分:2)

something.equals(null)只是false

查看java.lang.String#equals implementation:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {   // null is NOT instance of String 
        ...
    }
    return false;
}

答案 2 :(得分:0)

如果你这样做:

color.equals("pink");

它会抛出一个NPE。

但是

“粉红色” 字符串

"pink".equals(color); 

相同
"pink".equals(null);

如果你试图避免使用NPE,最好选择A.equals(B)并总是选择你认为不是 null 的A对象,如 常量 枚举

答案 3 :(得分:0)

在访问属性或在Null引用上调用方法时抛出NPE,这是由JVM而不是代码完成的。我已经看到一些实现的实例,如果参数为Null,那么抛出NPE的一些方法,但这是错误的实现,在那些情况下,IllegalArgumentException更有意义。

在String equals方法的情况下,完成以下事项:

  1. 检查两个引用是否相同

  2. 检查传递的参数是否为String类型,如果是这样的话:

    一个。从两个字符串中获取char数组,并从左到右逐个比较每个字符。如果一切顺利,返回真实

  3. 否则返回false

  4. 所以,重点是代码不应该抛出NPE,它们使得实现更容易出错。有更好的方法可以做到这一点。