This question already has answers here:
object==null or null==object?
(11 answers)
Closed 5 years ago.
When checking for nulls I use this:
String str;
if(str == null){
//...
}
but I've seen this as well:
if(null == str){
//...
}
Is there any advantage of using one over the other? Or is it just to improve readability?
The second version ( null == str ) is called a yoda condition.
They both result in the same behavior, but the second one has one advantage: It prevents you from accidentally changing a variable, when you forget one =. In that case the compiler returns an error at that row and you're not left with some weird behavior of your code and the resulting debugging.
The null == x convention is usually found in code written by people familiar with C, where an assignment can also be an expression. Some C programmers write code like this so that if they miss an = in
if (NULL == ptr)...
the code will not compile, since NULL = ptr is not a valid assignment. This prevents a rather sneaky error from being introduced in the code-base, although modern C compilers make make such conventions obsolete, as long as one takes care to enable and read the generated warnings...
This coding style has never had any usefulness in Java, where reference assignments cannot be used as boolean expressions. It could even be considered counter-intuitive; in their natural language most people will say "if X is null...", or "if X is equal to 17...", rather than "if null is equal to X...".
There's no difference between the two other than readability. Use whichever makes more sense to you.
As you stated readability is the most important reason. Reading it out loud, the (null == str) does not read well. It's almost like reading right to left. (str == null) reads much better.
In addition, I think the following needs to be taken into consideration:
if (str != null)
if (str == null)
vs.
if (null != str)
if (null == str)
I would expect the positive (str == null) and the negative to be written in the same manner, which is another reason I would favor the top set.
if (null == str) {
}
is a programming idiom from c/c++, where the assignment operator = can be used to resolve to a true/false statement. For example in c if you want to check if I can open a stream in c/c++, you can
if (myStream = openStream())
which sets opens and assigns in one line. However, this means that people often type = when they mean ==, and it would be valid syntax in c: for example if (x = 5) will always resolve to true, when they really mean if (x ==5). So people write if (5 == x) so if you leave out a = your code won't compile.
This doesn't apply to java.
There is no real difference. However the second is considered less error prone. In the first case you would not get an error if you tried to do
String str;
if(str = null){
}
which is something you usually don't do in conditionals.
Also, you get to think about the actual condition first, which is a good practice.
if(a==b) {} is the same as if(b==a) {} , and the same is true if b was null. It's just a style/order difference as far as functionality, at least in java.
Some developers argue that var == null is more error-prone than null == var. Their argument is that you might accidentally assign the variable instead of doing a null-check.
But only when the variable you test against null is a Boolean you can accidentally use the = instead of == and it will compile.
Boolean checked = Boolean.TRUE;
if(checked = null){ // accidentally assigned null and compiles
}
Only in this case the assignment compiles, because the conditional expression must evaluate to a boolean value. See JLS-14.9. Since the assignment expression itself evaluates to a boolean type, it compiles. But you will get a NullPointerException at runtume, because java will try to unbox the checked variable which is null.
If you use any other type then Boolean you will get a compiler error. E.g.
String str = "hello";
if(str = null){ // compiler error, because str = null doesn't evaluate to a boolean
}
My conclusion is that error situations are extremly rare and you can easily write unit tests that detect such errors.
So write the if-statement it in the way it is more readable.
I think "if name is null" makes more sense then "if null is name".
Related
I'm a fairly new beginner to java and was practicing some leetcode here: https://leetcode.com/problems/same-tree/
My solution to the question was:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null){
return true;
}
return (p.val == q.val)&&(p != null && q != null)&&
isSameTree(p.left, q.left)&&
isSameTree(p.right, q.right);
}
}
and I just couldn't get it to work with it resulting in a nullpointer error. But then a mere switch of the conditional:
return (p != null && q != null)&&(p.val == q.val)&&
isSameTree(p.left, q.left)&&
isSameTree(p.right, q.right);
and all of a sudden it works. No idea why. I thought && was a logical and operator, and so A and B is the same as B and A ... what's going on?
In most programming languages, the expressions are evaluated from left to right. In your earlier approach, p.val may result in NullPointerException when p is null. To avoid this, you should always check the null conditions before in your AND/OR expressions. Which is exactly what you did (without realizing I guess.).
In math or boolean algebra or whatever, the AND operator has the associative and the commutative properties, so math-wise, no.
However, most all programming languages use lazy evaluation for their Boolean and operators. If the first operand is false and the operator is &&, then why bother evaluating the second operand if you know it is just going to return false?
Using that, you can avoid errors (like the one you posted) by changing the order of the operands.
Like, if you wanted to avoid a object is undefined error when trying to access an object's members, you can do if(object != undefined && object.isExample). If object is undefined, then it it knows that that expression is false and quits there.
The && operator is stand for 'and' in logic, which returns true only if both of conditions are true.
So, the left condition checked first, and if it is false, the right condition isn't checked.
Because of that, I suggest you to put the conditions by this order (the higher in this order should be the left condition):
Must checked before working conditions (for example not null conditions).
Low time complexity conditions (for example checking the value of variable).
High time complexity conditions (for example searching in/sorting an array).
In order && operator to retrieve true all conditions need to return true so we first check the left conditions and only if its true we check the all the rest one by one,
If any condition fails we stop checking all others.
So in your case you need to get all the low complexity operation first
More reading about short circuit evaluation
https://en.m.wikipedia.org/wiki/Short-circuit_evaluation
This question already has answers here:
object==null or null==object?
(11 answers)
Closed 5 years ago.
When checking for nulls I use this:
String str;
if(str == null){
//...
}
but I've seen this as well:
if(null == str){
//...
}
Is there any advantage of using one over the other? Or is it just to improve readability?
The second version ( null == str ) is called a yoda condition.
They both result in the same behavior, but the second one has one advantage: It prevents you from accidentally changing a variable, when you forget one =. In that case the compiler returns an error at that row and you're not left with some weird behavior of your code and the resulting debugging.
The null == x convention is usually found in code written by people familiar with C, where an assignment can also be an expression. Some C programmers write code like this so that if they miss an = in
if (NULL == ptr)...
the code will not compile, since NULL = ptr is not a valid assignment. This prevents a rather sneaky error from being introduced in the code-base, although modern C compilers make make such conventions obsolete, as long as one takes care to enable and read the generated warnings...
This coding style has never had any usefulness in Java, where reference assignments cannot be used as boolean expressions. It could even be considered counter-intuitive; in their natural language most people will say "if X is null...", or "if X is equal to 17...", rather than "if null is equal to X...".
There's no difference between the two other than readability. Use whichever makes more sense to you.
As you stated readability is the most important reason. Reading it out loud, the (null == str) does not read well. It's almost like reading right to left. (str == null) reads much better.
In addition, I think the following needs to be taken into consideration:
if (str != null)
if (str == null)
vs.
if (null != str)
if (null == str)
I would expect the positive (str == null) and the negative to be written in the same manner, which is another reason I would favor the top set.
if (null == str) {
}
is a programming idiom from c/c++, where the assignment operator = can be used to resolve to a true/false statement. For example in c if you want to check if I can open a stream in c/c++, you can
if (myStream = openStream())
which sets opens and assigns in one line. However, this means that people often type = when they mean ==, and it would be valid syntax in c: for example if (x = 5) will always resolve to true, when they really mean if (x ==5). So people write if (5 == x) so if you leave out a = your code won't compile.
This doesn't apply to java.
There is no real difference. However the second is considered less error prone. In the first case you would not get an error if you tried to do
String str;
if(str = null){
}
which is something you usually don't do in conditionals.
Also, you get to think about the actual condition first, which is a good practice.
if(a==b) {} is the same as if(b==a) {} , and the same is true if b was null. It's just a style/order difference as far as functionality, at least in java.
Some developers argue that var == null is more error-prone than null == var. Their argument is that you might accidentally assign the variable instead of doing a null-check.
But only when the variable you test against null is a Boolean you can accidentally use the = instead of == and it will compile.
Boolean checked = Boolean.TRUE;
if(checked = null){ // accidentally assigned null and compiles
}
Only in this case the assignment compiles, because the conditional expression must evaluate to a boolean value. See JLS-14.9. Since the assignment expression itself evaluates to a boolean type, it compiles. But you will get a NullPointerException at runtume, because java will try to unbox the checked variable which is null.
If you use any other type then Boolean you will get a compiler error. E.g.
String str = "hello";
if(str = null){ // compiler error, because str = null doesn't evaluate to a boolean
}
My conclusion is that error situations are extremly rare and you can easily write unit tests that detect such errors.
So write the if-statement it in the way it is more readable.
I think "if name is null" makes more sense then "if null is name".
Ola,
Android/JAVA question, I need to test if a object is not NULL and if it's not NULL check a value, thus avoiding runtime error. As my vb.net background I'm used to;
if (not BackgroundWorker1 = nothing) andalso (backgroundworker.status = running) then
Is there a charming, 'one IF'/single line way to do this in JAVA?
Thanks!
Sure,
if ( backgroundWorker != null && backgroundWorker.status == running ) {
works in Java since the statements are evaluated from left to right.
There's a pretty direct translation:
if (BackgroundWorker1 != null && Backgroundworker1.status == running)
{
// "then" part here
}
Just like VB's andalso operator, Java also uses short-circuit evaluation with its logical operators.
The moral equivalent of andAlso in Basic is && in Java. Note, that there is no easy equivalent to plain and (i.e., the non-short-circuit version of the logical operator).
I have such code:
if(object != null && object.field != null){
object.field = "foo";
}
Assume that object is null.
Does this code result in nullPointerException or just if statement won't be executed?
If it does, how to refactor this code to be more elegant (if it is possible of course)?
&& does short circuit while & would not.
But with simple questions like this, it is best to just try it (ideone can help when you don't have access to a machine).
&& - http://ideone.com/LvV6w
& - http://ideone.com/X5PdU
Finally the place to check for sure would be the JLS §15.23. Not the most easy thing to read, the relevent section states:
The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.
Java does have short circuit evaluation, i.e. your code should be ok
One way to know it! Test it! How? Well, make a method which prints out something:
public static boolean test(int i)
{
System.out.println(i);
return false;
}
...
if (test(1) && test(2) && test(3))
{
// not reached
}
This prints:
1
So the answer on your question is "no".
Best way to find out would be try it, especially for a single line question. Would have been faster, too.
The answer is that Java will not execute the body of the "if".
This will not throw any NullPointerException . The condition will be evaluated from left to right and the moment first false expression is found it will not evaluate remaining expression.
Maybe this other question helps you:
Differences in boolean operators: & vs && and | vs ||
Java has short circuit evaluation, so it will be fine.
The code looks ok to me, but do you actually need to check object.field != null? I think that test can be omitted as you never use the variable, just set it.
On a side-note, most programmers wouldn't access fields directly (object.field) but rather through getters/setters (object.setField(x);). Without any more context to go on, I can't say if this is appropriate in your case.
&& and || conditions stops at the point they can decide whether the condition is true/false, in your case, the condition will stop right after object != null and I think that your code is just fine for this case
If you want all of your boolean expressions evaluated regardless of the truth value of each, then you can use & and | instead of && and ||. However make sure you use these only on boolean expressions. Unlike && and ||, & and | also have a meaning for numeric types which is completely different from their meaning for booleans.
http://ibiblio.org/java/course/week2/46.html
Although short circuiting would work here, its not a guarantee that (like I have done many times) you'll get the order wrong when writing another, it would be better practice to nest those if statements and define the order you want the boolean checks to break:
if(object != null)
{
if(object.field != null)
{
object.field = "foo";
}
}
This does exactly the same as you're essentially saying, if the first boolean check fails don't do the second; it is also nullPointerException safe as object.field will not be checked unless object is not null
Using short-circuiting on booleans can become annoying later on as when you have a multiple bool if statement it becomes trickier to efficiently debug which part short circuited.
I have this piece of code:
private void prepareContent() {
log.info("do something");
// success?
boolean suc = false;
suc = suc || uncompressToContent("file.tar.gz");
suc = suc || uncompressToContent("file.tgz");
for (int i = 0; i <= 9; i++) {
suc = suc || uncompressToContent("dir/" + i + ".tgz");
suc = suc || uncompressToContent("dir/" + i + ".tar.gz");
}
if (!suc) {
log.error("unable to do something");
}
}
The function returns false for "file.tar.gz" and file.tgz".
The problem is the the call to uncompressToContent("dir/1.tgz") returns true and the code stops its execution. The remaining code is not executed.
I'm not sure if this is an error in the compiler. What do you think?
Added: I forgot to mention that I need to execute all the calls to uncompressToContent and check if any returns true, using the fewer instructions as possible.
There is no error in the compiler.
As soon as suc is set to true (i.e. from the first uncompressToContent call) then all of the future expressions will return true without calling uncompressToContent. This is becuase you are using short circuit boolean or ("||") which do not evaluate the second argument if the first argument is true.
If you want all the calls to be made, use the normal or operator ("|") instead.
If the uncompress method returns true if there was a successful decompression, then suc would become true the first time that this happens. Once suc is true, all the other conditions would be true as soon as suc is evaluated, so the other part of the OR would not be evaluated. Thus, no decompressions will be attempted once at least one is successful.
This is called short circuiting and is the correct behavior and is a very useful property in most languages. And is also not a compiler optimization since it is part of the defined behavior of the language.
Beyond this answer, there are, I think, ways to make this code more readable.
First, are you sure that you want to OR rather than AND here? It seems like you want to quit as soon as one file did not compress decorrectly, not stop as one did decompress correctly.
Second, a better design, IMHO, would be to create a list of all the filenames you want to decompress, and then do a for-each over that list and do all the decompressions, it would make things more readable.
Third, if in most cases decompression would be successful, I think that exception handling is much better than boolean return values.
Here is how I would write something like this (and I would break it into functions)
List<String> filenames = new ArrayList<String>();
this.collectFilenamesToDecompress(filenames) // Write one or more than one functions of this sort based on the semantics of your problem
try
{
for(String filename: filenames)
{
uncompressFile(filename); // This will throw an exception if there is a failure
}
} catch(Exception e)
{
// Announce that there was an error and you stopped decompressing because there was an error.
// Return or quit
}
// If you got here, everything is great!
This behavior is by design.
Logical operators in most languages are short-circuiting.
In the expression a || b, b will only be evaluated if a is false.
Therefore, once suc becomes true, none of the other calls to uncompressToContent will be evaluated.
I think the compiler is doing something like: suc = uncompressToContent("file.tar.gz") || uncompressToContent("file.tgz") || uncompressToContent("...") || ... So, when it finds one true value, the execution is stopped. Is this feature documented?
Yes. It is clearly documented in the Java Language Specification section 15.24, where it says this:
"The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false."
The JLS then goes on to explain exactly what happens in excruciating detail. Follow the link above if you are interested.
Oh yea, and in this respect the Java || operator behaves the same as in C, C++, C#, Perl and many other programming languages.