Comparing Java boolean matches with ternary operator

I found a nice situation where I don't understand at all related to the Java boolean operator. I know and endorse the official oracle documentation here , which is && & and || have an advantage over ternary operator?

Now I have a strange line in my code like this

if (a.getItem() != null && a.getItem().getOtherItem() != null?true:a.getItem().getOtherItem().getSomevalue())
{
......
}

      

What I get is, well, nice java.lang.NullPointerException in a.getItem (). getOtherItem () becouse a.getItem () is null. How can I solve it, encapsulate it between brackets

if (a.getItem() != null && (a.getItem().getOtherItem() != null?true:a.getItem().getOtherItem().getSomevalue()))
{
......
}

      

So my question is, why am I getting a NullPointerException if I follow the official documentation previously linked && & takes precedence over ?: and && is evaluated for short-circuiting (there are a few questions also encountered here ).

+3


source to share


3 answers


You seem to be confused about what "higher priority" means. Let's explain with a simple example:

The operator *

has higher precedence than the '+' operator. This means that the expression a*b+c

evaluates to (a*b)+c

. The same goes for operator &&

and ternary operator:

&&

has a higher precedence than operator ? :

. This means that the expression a&&b?c:d

evaluates to (a&&b)?c:d

.


Hence, operator precedence works as described in your example. It does exactly what you asked:

if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                       true:a.getItem().getOtherItem().getSomevalue())

      

If a.getItem()

not zero, but a.getItem().getOtherItem()

has no null value for true , otherwise - a.getItem().getOtherItem().getSomevalue()

. Therefore, when any of the values ​​are NULL, the code will try to evaluate the third term, which will result in a NullPointerException

.

It is not clear what you really want to achieve. In the second example, you say:

if (a.getItem() != null && (a.getItem().getOtherItem() != null?
                            true: a.getItem().getOtherItem().getSomevalue()))

      

so you want to interpret the case when not a.getItem()

null

as false

, but in parentheses you are asking for an interpretation of the when a.getItem().getOtherItem()

not null

how true

, while the case whena.getItem().getOtherItem()

null

should call getSomevalue()

to be called in the link you just proved null

.

What you most likely want to do is evaluate a.getItem().getOtherItem().getSomevalue()

if all values ​​are non-zero:



if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                     a.getItem().getOtherItem().getSomevalue(): false)

      


Note that you can express the same without the ternary operator. The equivalent statement would be:

if (a.getItem() != null && a.getItem().getOtherItem() != null
                        && a.getItem().getOtherItem().getSomevalue())

      


In the case where the return value should be true

, as in

if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                     a.getItem().getOtherItem().getSomevalue(): true)

      

the same can be expressed as

if (a.getItem() == null || a.getItem().getOtherItem() == null
                        || a.getItem().getOtherItem().getSomevalue())

      

Whenever you see true

or false

in a compound expression boolean

, you can be sure that something is wrong.

+6


source


A common use case for ?

is to replace if

in a simple assignment branch, for example:

int a;
if(isOdd(b) || isPrime(b))
{
  a = b;
}
else
{
  a = -b;
}

      

in just



int a = isOdd(b) || isPrime(b) ? b : -b;

      

And for this use case it makes sense that &&

u ||

take precedence over ?

.

Confusion only arises if it ?

returns boolean

as you use it internally if

, which is very rare in my experience.

0


source


I would say that in your if statement

if (a.getItem() != null && a.getItem().getOtherItem() != null?true:a.getItem().getOtherItem().getSomevalue())

      

first the following internals should be evaluated:

null?true:a.getItem().getOtherItem().getSomevalue()

      

so the next part can be put together

if (a.getItem() != nulla.getItem().getOtherItem() !=<result_from_most_inner_part>)

      

This if statement is ugly anyway. Make the code readable enough and the compiler will do its part: P

0


source







All Articles