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 ).
source to share
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.
source to share
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.
source to share
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
source to share