0

I understand that trying to compare the value of an Object that's null with something will result in a NullPointerException, e.g.,

String bob;
if(bob.equals("blahblahblah")){do_something();}

and that it's a good idea to use nested checks like so:

if(!bob.equals(null)){
    if bob.equals("blah blah blah"){
      do_something();
    }
}

But if I haven't given bob any value yet, I get an error when I run the above saying bob hasn't been initialized - since I'm comparing bob to null, I should be able to run this without a problem, shouldn't I?

Thanks.

Raul Guiu
  • 2,374
  • 22
  • 37
  • 1
    ofcourse bob is `null` : http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception?rq=1 – jmj Mar 28 '14 at 17:09
  • You are right that you can compare bob to null, but you would use the == operator in that case. For string comparisons (on non null values, meaning after a null check) you use the .equals method. its not the comparison that throws the exception, its the call to a .equals method on an object (bob) which is null. – Mark W Mar 28 '14 at 17:12
  • @JigarJoshi No, `bob` is uninitialised, there's a big difference. – JonK Mar 28 '14 at 17:14
  • 1
    what is the difference ? – jmj Mar 28 '14 at 17:15
  • Uninitialised variables can potentially contain *absolutely anything*. The memory that the JVM allocated to that variable holds whatever it held before the JVM grabbed it for the variable. Until you initialise something, you can't know what that variable holds, it's completely meaningless, and in languages like C where initialisation isn't forced by the compiler, results in undefined behaviour. In order for something to be `null`, it must first have been initialised. – JonK Mar 28 '14 at 17:20
  • 1
    @JonK Java is not C. In Java variables are either initialized by user/programmer, or have default values (`false` for boolean, `0` for numeric values, `null` for references). If variable will not be initialized and tried to use, code will not compile. BTW only class fields are set up by compiler to have default value, local variables (the ones declared in method need to be initialized by user/programmer). – Pshemo Mar 28 '14 at 17:23
  • @Pshemo false and null are really 0 as well :) (even if java hides this from you) – Cruncher Mar 28 '14 at 17:37
  • @Pshemo `final` fields do not get initialised to default values either. `class fields` to me means `static`; non-`final` member variables will also initialise to defaults. At any rate, I was answering the question of what's the difference between *uninitialised* and *null*. Yes, Java compilers enforce that a variable *must* have been initialised before you can use it, but until it's initialised what I said holds true. – JonK Mar 28 '14 at 18:39
  • @JonK "*`final` fields do not get initialised to default values either*" that is not true. `final` values are also initialized with default values. It just happens that they demand to only once explicitly set up their value (for example in constructor). Take a look at this code http://ideone.com/3WBL76 and you will see what I mean. – Pshemo Mar 28 '14 at 18:50
  • 1
    @JonK Most problematic sentence in your comment is that "*The memory that the JVM allocated to that variable holds whatever it held before the JVM grabbed it for the variable*". You are saying for example about case where `int i; /*some time passes*/ i=42;` In this case memory for `i` before `i=42` could in fact not reset, so it can be any set of bits, but we can't check it because Java explicitly demands to initialize it before it can be used (as [jls-4.12.5](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5) describes). – Pshemo Mar 28 '14 at 19:12
  • @Pshemo I hadn't realised that about `final` varibles, thanks for the link, was interesting. – JonK Mar 29 '14 at 01:19

6 Answers6

3

if bob is null you can't do bob.equals - you need to check

if (bob != null)

like this

if (bob != null) {
    if (bob.equals("blah blah blah")){

          do_something();
    }
}

A nice way to get around it is

if ("blah blah blah".equals(bob)) {

}
Aidan
  • 1,550
  • 1
  • 13
  • 20
2
!bob.equals(null)

You are trying to call a method on a null object, thus you'll get errors. Try this instead:

bob != null
Zyn
  • 614
  • 3
  • 10
2

Imagine writing

null.equals(null)

Would you expect it to work? This doesn't work for the same reason. As other stated, you can use reference compare (==) for this, since there is only 1 null.

Cruncher
  • 7,641
  • 1
  • 31
  • 65
1

your bob is null and you can not call equal() on that either change your program to

if(bob != null){
    if bob.equals("blah blah blah"){
      do_something();
    }
}

OR

initialize bob like String bob = new String("some string");

Ashish
  • 14,295
  • 21
  • 82
  • 127
  • I don't know about this initialized keyword. Is that Java? – mttdbrd Mar 28 '14 at 17:14
  • I don't see initialized in the list of Java keywords: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html – mttdbrd Mar 28 '14 at 17:15
  • It's not about spelling. There is no "initialize" or "initialized" keyword in Java. Is that Scala or Groovy or something? – mttdbrd Mar 28 '14 at 17:16
  • Oh. Remove the code markdown for initialize though and that'll clear up any potential confusion. I see what you were saying. – mttdbrd Mar 28 '14 at 17:17
  • oh I am sorry I did not mean initialize a keyword I was just trying to say initialize some value in it. – Ashish Mar 28 '14 at 17:18
1

As Shreyos pointed out, you never initialize bob so you get the NPE. You can safeguard against this by using Yoda Conditions:

if("blahblahblah".equals(bob)){do_something();}

Your string literal can never be null so the equals() comparison will return false when bob is, in fact, null. Many scoff and joke about using such techniques but they can be handy in many cases.

evanchooly
  • 6,102
  • 1
  • 16
  • 23
0

Your problem is this:

if(!bob.equals(null)){
    if bob.equals("blah blah blah"){
      do_something();
    }
}

Assuming you declared this with String bob; The compiler will default that to String bob = null;

null is a pointer (reference) all by itself. The method String.equals() is a method that is referenced in the String class. Since you didn't create a object of type String, the class doesn't exist and therefore neither does the method.

If you're going to test to see if something is null (as you will when you eventually write production code) you're going to use the equals operator like this:

if( null != bob ){ //operations on bob }

EXTRA DETAIL:

Now initialization is like this, When you say something like:

String bob = "foo";

The compiler is actually going to write something like String bob = new String(foo);

This should tell you then that initialization means object creation.

I say "something like" because the following is also possible:

String bob = "foo" + "bar";

The compiler is going to write

String bob = new StringBuilder("foo").append("bar").toString();
avgvstvs
  • 6,196
  • 6
  • 43
  • 74