-2

If I have a basic program to compare a null string, why does the location of the null string potentially blow up and give a NullPointerException?

The first 3 prints will print, false, null: null, and then null... but the last one, which should be just like the first print statement, throws an exception.

Why is this?

String teststring = null;

System.out.println("".equals(teststring));
System.out.println("null: "+null);
System.out.println(teststring);
System.out.println(teststring.equals(""));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
Jayizzle
  • 532
  • 1
  • 6
  • 24
  • What do you think of this: `null.equals("")`? If you expect that to throw a `NullPointerException`, then why do you expect that `teststring.equals("")` works when `teststring` is `null`? – Luiggi Mendoza Feb 11 '16 at 17:47

3 Answers3

3

the method equals is not required to throw a NullPointerException if the argument is null. However, invoking a method on a null object is not valid, and thow a NPE

So "somestring".equals(null) return false by convention.

null.equals("somestring") is invalid, and throw a NPE

Jérémie B
  • 10,611
  • 1
  • 26
  • 43
  • then why isn't it good practice to have "string".equals(stringobject) instead of what I commonly see in industry, stringobject.equals("string) – Jayizzle Feb 11 '16 at 17:50
  • 1
    it's a good practice to have "string".equals. by default, analysis tools like sonarqube have a rule on this syntax – Jérémie B Feb 11 '16 at 17:51
  • @Jayizzle: because throwing `NullPointerException`s can be good for you. Nulls frequently indicate a bug in your program, and not throwing up on them can hide the bug and make it harder to trace. – Louis Wasserman Feb 11 '16 at 18:06
3

equals(Object) is just a method, like any other method, there's nothing magical about it. If you call it on a null reference, you'd get a NullPointerException. The elegant solution to this, since Java 7, is to use Objects#equals(Object, Object), which is null-safe:

System.out.println(Objects.equals(teststring, ""));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

This is because you are invoking a method on a null object, therefore you get a NullPointerException !

However when you do "".equals(teststring) you are actually invoking the equals methods of the "" String (if it's easier to you, consider "" as new String("")). Also note that it is considered as a best practice to call the .equals() method on the "safe" string (the one we know that is not null !).

For the third assertion, "null" is display simply because under the hood println calls a method print which is the following :

 /**
 * 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);
}

So we can clearly see that there is a special case for null Strings !

I would strongly suggest you to read up : https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html which is the official documentation of the NPE

Louis F.
  • 2,018
  • 19
  • 22