What is recommended in java :
if(!var){
}
or
if(var==null){
}
and why?
It is the same thing with Groovy?
In java, if var is null,
if( !var ) {
// var is not null
}
Won't work as ! is for booleans.
In Groovy, it will work as it applies Groovy Truth.
HOWEVER, if you are testing for null, then you should use the explicit test
if( var != null ) {
// var is not null
}
Even in Groovy, as if var was anything Groovy considers false, the first comparison would pass, ie:
assert !0
assert !''
assert ![]
assert !null
Of course you can also use the null safe operator:
def map = [ person:[ tim:[ login:'tim_yates' ] ] ]
assert map?.person?.tim?.login == 'tim_yates'
assert map?.person?.alice?.login == null
The first one in Java would apply only to booleans
The unary operator ! does the negation operation. For example,
!false will yield true.
And == does comparison operation.
They both are completely different to each other. In java, you can use the negation operator only with boolean values, whereas the comparison operator can be used to compare values.
Also, in Java, if var is Boolean and is null, then
if(!var){ // would throw a NullPointerException
}
Related
Is it possible to do something like this?
dog.setIsBarkingIndicator(mailman.getIsAtDoor() != null && mailman.getIsAtDoor().equals("N") ? false : true);
But for what I researched, this is basically the same as: dog.setIsBarkingIndicator(mailman.getIsAtDoor() == null || !mailman.getIsAtDoor().equals("N"))
So it actually sets it at false if its null or not equals to "N"? Did I understand correctly?
Is there any way to check the null without using the if condition?
Thank you!
So, your logical condition is basically like the following:
mailman.getIsAtDoor() == null || !mailman.getIsAtDoor().equals("N")
You can change the instance which performs equal operation. The one instance here is a constant string literal - that means it is never a null value, so it can always perform an equality operation. The condition you are looking for is here:
!"N".equals(mailman.getIsAtDoor()).
This approach does not require from you to check null value of the mailman.getIsAtDoor().
Perhaps the dog or the mailman variable is null. So please try the following code:
if (dog != null && mailman != null)
{
dog.setIsBarkingIndicator(!mailman.getIsAtDoor().equals("N"));
}
Here is the Java code:
public static boolean anyEqual(Object needle, Object... haystack) {
if(needle == null || haystack == null) {
return false;
}
if(haystack.length == 0) {
return false;
}
for(Object match : haystack) {
if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
return true; // warning from IntelliJ here, 'contract clause !null, null -> false is violated'
}
}
return false;
}
Does anyone have any idea why this is being shown? contract clause !null, null -> false is violated? Thanks!
IntelliJ 14.0.2 build: 139.659
Screenshot:
IntelliJ is inferring the formal contract of your method to be this:
null, _ -> false; !null, null -> false
What this actually means:
The first contract specifies that, so long as the first parameter is null, it will return false. This is observed by your first if statement:
if(needle == null || haystack == null) {
return false;
}
The second contract specifies that, if the second parameter is null, then it will return false. This is also specified by the same if statement above.
My gut is telling me that IntelliJ is having some trouble discerning what the loop's formal contract is in addition to all of the above, although it'd be as simple as another condition in the contract expression.
for(Object match : haystack) {
if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
return true;
}
}
Let's briefly go through this.
The enhanced-for statement won't fire if haystack is of length 0, so that's something to take into consideration.
The elements inside of the array could be null, and I'm not entirely sure that IntelliJ's static analysis covers that piece yet.
We've established already that needle must be non-null, so there's nothing violating the contract at that line.
If we have a scenario in which match != null && needle.getClass() == match.getClass() && needle.equals(match) is true, we return true. Otherwise, we return false.
There's nothing that I can see in the formal documentation that gives us the expression we require to say, "hey - we're checking elements of an array!"; it may be the case that the analysis is tripping up on the fact that we're returning true in spite of what we stated above (since haystack is non-null).
Allow me to stress this point:
haystack has to be non-null in order for you to enter into the enhanced-for. Your code will not work otherwise.
All in all, I wouldn't worry about it. Better yet, file a bug against it so that this sort of thing could be fixed or expanded upon.
This looks like an IntelliJ bug to me, since by removing the static keyword from the method the warning disappears.
Something must be confusing the static analysis here. One can always submit this to youtrack so jetbrains devs can look at it.
Someone already reported this issue Here
(tested on v14.0.3)
This message is being shown because IntelliJ checks for method contract violations. It's a relatively new feature, read more at https://www.jetbrains.com/idea/features/annotation_java.html
I have a piece of code like follows
public class Test{
public static void main(String[] args) {
System.out.println(true?false:true == true?false:true);
-----------------------
}
}
The output is false. If you are using Eclipse you get a wavy (dashed here) line and warning like "Comparing identical expressions". Note the start of the wavy line.
I changed the code to the following
public class Test{
public static void main(String[] args) {
System.out.println((true?false:true) == (true?false:true));
---------------------------------------
}
}
The output is true. If you are using Eclipse you get a wavy (dashed here) line and warning like "Comparing identical expressions". Note the start of the wavy line now.
Why the difference?
Because ternary operator (?:) has lower priority than equality operator (==). This means that:
true?false:true == true?false:true
is actually interpreted as:
true?false:(true == true?false:true)
This, in turns, is evaluated to:
true?false:((true == true)?false:true)
cont.:
true?false:(true?false:true)
...and eventually:
true?false:(false)
and eventually:
true?false:false
And obviously this explains the output of the first code snippet. Eclipse correctly recognizes operator precedence and highlights possibly incorrect statement.
UPDATE: Thanks for all the comments. In fact I forgot about operator precedence on the left side. I checked the exact behaviour using the program below:
public static boolean a(char label, boolean result) {
System.out.println(label);
return result;
}
public static void main(String[] args) {
System.out.println(
a('a', true) ? a('b', false) : a('c', true) == a('d', true) ? a('e', false) : a('f', true)
);
}
The results are consistent with #Milad Naseri suggestion.
There is nothing unexpected here, the answer is operator precedence.
In the first case it is:
true?false:(true == true?false:true)
While the in the second case your paretheses override the precedence rules.
In case your problem is the difference of outcomes, this is because of the order of precedence of the operators you use. Check here for details. According to that order of precedence:
true ? false : true == true ? false : true
is the same as this:
true ? false : ((true == true) ? false : true)
so it will always evaluate to false. You could put anything after the colon since it's never evaluated anyway (if I remember correctly and the ternary operator uses lazy evaluation); the reason for this is that
true ? A : B
always evaluates to A.
On the other hand,
(true ? false : true) == (true ? false : true)
will have both sides of the comparison operator == evaluate to false, so
false == false
which is a true statement.
So the difference here is the order in which the operators are evaluated, which is determined by the parentheses you use and, if there is ambiguity that isn't resolved by parentheses, by the order of precedence of the operators that are used.
In general, the ternary operator "? :" works like this
A ? B : C
If A is true, evaluate to B, else evaluate to C. A has to be a boolean expression, B and C can be whatever you want; you'll have to deal with type mismatches though if you want to assign the evaluated value to a variable and they are of different types.
That is because the conditional equality operator (==) takes precedence over the ternary conditional ?:. So, in a?b:x==y?z:t x==y?z:t is evaluated before a?b:x and y?z:t are.
What's the utility method that parses a boolean String properly? By properly I mean
"true" => true
"false" => false
"foo" => error
The parse methods in java.lang.Boolean are dodgy - they don't distinguish "false" from "foo". Anything else in Java libraries (or Guava, or Commons Lang) that does it properly?
Yes it's just be a couple lines, I just rather not write any line that I shouldn't have to. :-)
Check out Boolean Utils form apache commons :
Boolean Utils API
Converts a String to a Boolean
throwing an exception if no match
found.
null is returned if there is no match.
BooleanUtils.toBoolean("true",
"true", "false") = true
BooleanUtils.toBoolean("false",
"true", "false") = false
if ( "true".equalsIgnoreCase(yourString) )
return true;
else if ( "false".equalsIgnoreCase(yourString) )
return false;
else
throw new Exception();
There's not one.
Honestly, this question is ridiculous. Yes, there are ways to do it built in (the Boolean utils API Apache Fan mentioned). But you're going out of your way to do something in a fancy way at the cost of A) productivity (stop wasting your time, write the three lines of code), and B) readability. What's easier to read:
if( "true".equals(myString) )
or
if( BooleanUtils.toBoolean(myString, "true", "false") )
I'd go for the first one every time. Even better, use the IgnoreCase option for the string comparison. The toBoolean is case sensitive, so "True" would actually throw an exception. Awesome! That's really useful!
How about the very simple:
EDIT: or am I missing the point...
boolean isTrue (String s) {
return theString.toLowerCase().equals("true");
}
In Java, you would usually say that
if(someBool != false)
is the same as
if(someBool)
But what if someBool is not of type boolean but Boolean, and its value is null?
If you want to handle Boolean instances as well as primitives and be null-safe, you can use this:
if(Boolean.TRUE.equals(someBool))
It will throw a NullPointerException (autounboxing of null throws NPE).
But that only means that you must not allow a null value. Either use a default, or don't use autounboxing and make a non-null check. Because using a null value of a boolean means you have 3, not 2 values. (Better ways of handling it were proposed by Michael and Tobiask)
Use ApacheCommons BooleanUtils.isTrue() or .isFalse()
If someBool is Boolean
if (someBull != null && someBull) {
//Yeah, true.
}
Since Boolean can be null make sure you avoid NullPointerException by checking for not null.
I did a little test:
Boolean o = null;
try {
System.out.println(o ? "yes" : "no");
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println((o != false) ? "yes" : "no");
} catch (Exception e) {
e.printStackTrace();
}
The output is surprising:
java.lang.NullPointerException
at btest.main(btest.java:10)
java.lang.NullPointerException
at btest.main(btest.java:15)
The first NPE is to be expected, because o will be autounboxed (and that fails because it's null). The second happens for the same reason, but it doesn't feel natural. Anyway, the solution is to do:
System.out.println(!Boolean.FALSE.equals(o) ? "yes" : "no");
You can however compare a null Boolean with a Boolean instance. For example :
Boolean myBool = null;
System.out.println(myBool == Boolean.FALSE);
System.out.println(myBool == Boolean.TRUE);
prints :
false
false
Good illustrations of the difference between the primitive boolean & the object Boolean. The former can be only true or false. The latter can be true, false, or unknown/undefined. (i.e., null). Which you use depends on whether you want to deal with two use cases or three.
It's old, but Boolean.valueOf(null) is false, just like Boolean.valueOf(false) is false.
Actually the Boolean constructor accepts null, returns FALSE and doesn't throw a NullPointerTantrum.
new Boolean(null);
<false>
This has the added bonus of also giving a thruthy response to the string "true" which is not the case for Boolean.TRUE.equals but we are more restricted again having only constructors for Strings and Booleans.
Something you can overcome with string concatenation, which is also null-proof.
new Boolean(""+null);
<false>
new Boolean(""+false);
<false>
new Boolean(""+new Object());
<false>
new Boolean(""+6);
<false>
new Boolean(""+new Integer(9));
<false>
Ensuring that all the TRUE options, available in java, still remains.
new Boolean(""+true);
<true>
new Boolean(""+"true");
<true>
If it's Java 7+ you can use
import java.util.Objects;
And
if (Objects.equals(someBool, true))
As Boolean will give you an object, you must always check for NULL before working on the object
If its null then you'll get a NullPointerException