为什么 String.equals() 的顺序对于比较字符串很重要?如果有空字符串,可能会抛出异常

Why does order of String.equals() matters for comparing strings? If theres a null string, there could be a exception thrown

如果我有一个比较 null 字符串的基本程序,为什么 null 字符串的位置可能会爆炸并给出 NullPointerException

将打印前 3 个打印件,falsenull: null,然后是 null... 但是最后一个,应该就像第一个 print 语句一样,抛出异常。

这是为什么?

String teststring = null;

System.out.println("".equals(teststring));
System.out.println("null: "+null);
System.out.println(teststring);
System.out.println(teststring.equals(""));

如果参数为 null,方法 equals 不需要抛出 NullPointerException。但是,在空对象上调用方法是无效的,并且 NPE

所以 "somestring".equals(null) return 按照约定为 false。

null.equals("somestring")无效,抛出一个NPE

equals(Object)只是一种方法,和其他方法一样,没有什么神奇之处。如果你在 null 引用上调用它,你会得到一个 NullPointerException。优雅的解决方案,因为 Java 7,是使用 Objects#equals(Object, Object),它是空安全的:

System.out.println(Objects.equals(teststring, ""));

这是因为您在 null 对象上调用方法,因此您得到 NullPointerException !

然而,当您执行“”.equals(teststring) 时,您实际上是在调用“”字符串的等式方法(如果对您来说更容易,请将“”视为 new String(""))。另请注意,最佳做法是在 "safe" 字符串(我们知道它不是 null !)上调用 .equals() 方法。

对于第三个断言,显示 "null" 只是因为在引擎盖下 println 调用了一个方法 print,它如下所示:

 /**
 * Prints a string.  If the argument is <code>null</code> then the string
 * <code>"null"</code> is printed.  Otherwise, the string's characters are
 * converted into bytes according to the platform's default character
 * encoding, and these bytes are written in exactly the manner of the
 * <code>{@link #write(int)}</code> method.
 *
 * @param      s   The <code>String</code> to be printed
 */
public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

所以我们可以清楚地看到空字符串有一个特例!

强烈建议您阅读:https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html NPE 的官方文档