0

I am doing a question in CodeWar and I had encountered a few problems. The question basically accepts a Boolean array to count the number of sheep (true = add 1 to sumOfSheep, false does not add 1 to sum). This is the input and my code.

Boolean[] array1 = {true,  true,  true,  false,
                  true,  true,  true,  true ,
                  true,  false, true,  false,
                  true,  false, false, true ,
                  true,  true,  true,  true ,
                  false, false, true,  null };


public class Counter {
  public int countSheeps(Boolean[] arrayOfSheeps) {
    int sumOfSheep = 0;
    for(Boolean sheep:arrayOfSheeps){
      if(sheep){
        sumOfSheep++;
      }
      else if(sheep == null){
        continue;
      }
    }
    return sumOfSheep;
  }
}

After running this code, it will return a NullPointerException. I have tried to print out every element in the array and I noticed that it will crash when it encounters a null value.

if(sheep){
        sum++;
        System.out.print(sheep);
        System.out.println(" Good");
      }
      else if(sheep == null){
        System.out.println("Bad");
        continue;
      }

The program won't crash if I change the if statement's condition to if(sheep != null && sheep). Can I know why is this happening??

616Hz_lim
  • 21
  • 6
  • 3
    Does this answer your question? [java.lang.NullPointerException with boolean](https://stackoverflow.com/questions/25824269/java-lang-nullpointerexception-with-boolean) – OH GOD SPIDERS Nov 09 '20 at 15:50
  • 1
    Because you array is `Boolean[]`, not `boolean[]`. This allows for null values. If you evaluate an element of that array, auto-unboxing is performed. That turns a Boolean into a primitive `boolean` using `var.booleanValue()`. If `var` is `null`, a NPE is thrown. – f1sh Nov 09 '20 at 15:51
  • Okay thank you!! Then can I ask why `sheep == null` will crash and `sheep != null` won't crash?? – 616Hz_lim Nov 09 '20 at 16:00
  • @616Hz_lim neither `sheep == null` nor `sheep != null` will cause any NullPointerException. Both are fine. The Problem is when Java tries to convert your `Boolean` to a `boolean` which cannot be done for `null`. In case of `if(sheep != null && sheep)` it will only ever try to even evaluate the part after `&&` if the first `sheep != null` passes as `true` because of [short circuiting](https://stackoverflow.com/questions/8759868/java-logical-operator-short-circuiting) – OH GOD SPIDERS Nov 09 '20 at 16:07

1 Answers1

1

The error is in the indicated line, not in the else if:

  if (sheep) {                 // <-- FAILS if sheep == null
    sumOfSheep++; 
  } else if(sheep != null){    // <-- always safe, as is !(sheep == null)
    continue;
  }

The problem is that, if sheep is a Boolean (and thus a reference to an object), trying to convert it to true or false (by looking at whether it is pointing to Boolean.TRUE or Boolean.FALSE) will, when it is actually pointing to null, throw NullPointerException. You need to compare it against Boolean.TRUE instead:

  if (sheep == Boolean.TRUE){ // Boolean.TRUE == sheep would have also worked
    sumOfSheep++;
  }

Comparing object references with == is always fine, regardless of whether some are null, because no conversion will be attempted. Trying to convert a null reference to a boolean (or any non-reference), on the other hand, fails as it should.

tucuxi
  • 17,561
  • 2
  • 43
  • 74