Why is FindBugs showing warning for redundant null check - java

if (first != null && second != null && !first.equals(second)) {
// not null & not equal
} else if (first == null ^ second == null) {
// not both null and not both not null
// (first == null && second != null) || (first != null && second == null)
} else {
// both null or equal
}
FindBugs is complaining about else if (first == null ^ second == null) {...}

Since you wrote in the comment: not both null it's a good thing that FindBugs showed you your (potential) mistake since you should have used && (AND) not ^ (XOR):
first != null && second != null
or alternatively:
!(first == null || second == null)
UPDATE:
The OP change the comment to: "not both null and not both not null" this condition requires a different if:
(first == null && second != null) || (first != null && second == null)
which is equivalent to:
first == null ^ second == null
only that the former version is more readable.

Probably because it is only software.

The ^ operator is a bitwise operator as opposed to a logical operator. While technically correct the precedence of the operators makes the expression confusing should the logical expressions grow. I don't use FindBugs but I would call the 3rd line suspect - Wrap it in parentheses or rewrite it.
...
} else if ((first == null) ^ (second == null)) {
...
^ can behave like a logical operation as long as the operands are boolean values. Because the precedence is different for each logical and bitwise operator, you should always group with parentheses since the order of evaluation will not be left to right but will be based on the table here: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
Your expression "not both null" and "not both not null" comes out like this:
(first == null) || second == null) && !((first == null && second == null))
Which is pretty confusing but it is what you are asking for.
I am not sure what you are doing in the blocks but it might be easier to write the entire block like this:
if(first!=null && !first.equals(second)) {
// first is not null and the first and second are not equal
} else if (second!=null && !second.equals(first)) {
// second is not null and first and second are not equal
} else {
// all that is left is that first and second are both null OR neither one is null but they are equal
}

The warning says: redundant null check. Thus, FindBugs thinks that you are redundantly checking the nullity of the variables. Try if this code also triggers the warning:
Boolean firstNull = (first == null);
Boolean secondNull = (second == null);
Boolean equalFirstSecond = first.equals(second);
if (!firstNull && !secondNull && !equalFirstSecond) {
// not null & not equal
} else if (firstNull ^ secondNull){
// not both null and not both not null
} else {
// both null or equal
}

if (first != null && second != null && !first.equals(second)) {
You don't need to test second != null here. The equals() call does that.
} else if (first == null ^ second == null) {
You should return false in this case, assuming this is an equals() method itself.
If FindBugs doesn't like it with this change I would ignore it, it doesn't know what it's talking about. It's not perfect. Put in an exception rule.

Related

Why is the conditional (ternary) operator evaluated in a logical AND when the lhs is false

return super.isAvailable() && expander != null
&& rightNotLeft ? !expander.isExpandedRight() : expander.isExpandedRight();
My problem was that when expander was null I was getting a null pointer exception. But I didn't think that this should happen since expander!=null is being evaluated to false and since ANDs are being used the entire expression should short circuit and return false.
return super.isAvailable() && expander != null
&& (rightNotLeft ? !expander.isExpandedRight() : expander.isExpandedRight());
The above code (adding the parentheses) solved the problem. However this does not make sense to me as no matter what happens in the conditional operator there is no way to return true so shouldn't it short circuit?
Thank you for your responses.
This is due to operator precedence. Your condition without explicit parentheses is actually evaluated like
return (super.isAvailable() && expander != null
&& rightNotLeft) ? !expander.isExpandedRight() : expander.isExpandedRight();

Java boolean return types

I'm confused by this code, I thought for a boolean you must return 'true' or 'false' and nothing else so why does this code work?
public static boolean diagonal(Location l, Location l1) {
return l.getX() != l1.getX() && l.getY() != l1.getY();
}
The != and && operators evaluate to a boolean result. They each perform a test and evaluate to the boolean values true or false depending on the results of the test (the first tests inequality, the second is a logical AND).
See JLS 15.21 for a description of equality operators and what they evaluate to. In particular:
The type of an equality expression is always boolean.
See JLS 15.23 for a description of the conditional AND operator and what it evaluates to. In particular:
The type of a conditional-and expression is always boolean.
Also try this:
System.out.println(5 != 5);
System.out.println(5 != 6);
System.out.println(true && false);
System.out.println(true && true);
This is returning a boolean. If l.getX() "does not equal" l1.get(X) "and" l.getY() "does not equal" l1.get(y), then "return true" otherwise "return false".
!= and && are binary operators that each return a boolean.
It is returning true or false.
l.getX() != l1.getX() && l.getY() != l1.getY();
Is a statement that checks if 1.get(X) is not equal to l1.getX() AND 1.get(Y) is not equal to l1.getY().
because
return l.getX() != l1.getX() && l.getY() != l1.getY();
is a boolean expression and return statement would do the result
this is equivalent if you express the order
return ((l.getX() != l1.getX()) && (l.getY() != l1.getY()));
true or false it depends on result of the evaluation, and finally it return a boolean because only boolean operations performed.
boolean a = l.getX() != l1.getX();
boolean b = l.getY() != l1.getY();
boolean c = a && b;
return c;

Operator to choose upon the condition

I have a table which contain two columns in database status and diff_id status column may contain these values
DFG_SGG_RGRG
NULL
EF_SFEG_FTT
IFEF_RGG
abc_id may contain these values
null
43546
45346
45746
53465
Now I am getting these values in an object t ,so I have to make an condition where status column is null and abc_id should have value 435465666L so I have prefer to write an if like shown below please advise is it correct as I am confused between && operator || operator
if ( if f.getStatus()== null || abc_id() .longValue()==435465666L )
{
//perform the logic
}
Please advise - is it correct approach?
& = "and"
&& = "and, but only if preceding condition was true"
| = "or"
|| = "or, but only if preceding condition was false"
If you're saying:
AND - use &&
OR - use ||
Remebmer also that && takes precedence over ||.
If both conditions must be true you need to use the && operator.
if (f.getStatus()== null && abc_id().longValue()==435465666L )
{
//perform the logic
}
Using the && operator causes a condition to be true only if both conditions are true. For example:
System.out.println(true && false); //prints false
System.out.println(false && false); //prints false
System.out.println(true && true); //prints true
System.out.println(false && true); //prints false
The || operator causes a condition to be true if one of the conditions is true.
System.out.println(true || false); //prints true
System.out.println(false || false); //prints false
System.out.println(true || true); //prints true
System.out.println(false || true); //prints true
use
if (f.getStatus()== null && abc_id().longValue() == 435465666L )
{
//perform the logic
}

servlet request.getParameterValues(fieldName) returns null and throw exception

i want to get parameters values and sometimes i do not send them and it return me null
and its ok . but when i preform check on the return string array the servlet throws a java.lang.NullPointerException
and i just what to do nothing when its null. ( continue the flow )
String[] values = null;
if(request.getParameterValues(fieldName).length>0)
{
values = request.getParameterValues(fieldName);
if(null!=values || values.length>0) // HERE IT throws NullPointerException
{
Collections.addAll(strlist, values);
}
}
It should be
if(null!=values && values.length>0)
because, if your values is null(evaluating to false), the OR condition in your statement, executes the other part of the OR, which throws the NPE.
If you give an && there, it'll SHORT-CIRCUIT the statement evaluation when it encounters a false at null!=values.
It's the AND && operator that should be used to test if both conditions are met, which is what you need in you instance.
if (null != values && values.length > 0)
in and unlike or if values is null it wont go for next check.
if(null!=values && values.length>0) // change to and
{
Collections.addAll(strlist, values);
}
also refer && (AND) and || (OR) in IF statements
&& and || follow short-circuit evaluation.
That is these operators wont execute right side expressions if not needed.
for && operator if false at LHS, then it wont execute next expressions
for || operator if true at LHS, then it wont execute next expressions
so for your condition check it needs && operation for avoiding NullPointerException
if(null!=values && values.length>0)

Getting NullPointerException with equals

im having trouble with null pointer errors in java, im trying to make a breakout game and i know what the problem is its this.
GObject collider = getElementAt( ballX, ballspeed);
if(collider.equals(paddle) && collider){
ballspeed = -ballspeed;
}
When the if statement it null the program gets the error.
Ive try this too but no luck
GObject collider = getElementAt( ballX, ballspeed);
if(collider.equals(paddle) && collider != null){
ballspeed = -ballspeed;
}
Try other way:
if(collider != null && collider.equals(paddle) ){
ballspeed = -ballspeed;
}
Read more about operators in java
Like others said :
if(collider != null && collider.equals(paddle) ) {
should do the trick. so an expression of this form:
if (condition1 && condition2)
Condition2 will be evaluation only if condition1 is true. In this case, if condition 1 is null, condition2 will not be evaluated and this would prevent null pointer exception.
You must do the null-check before you try to call equals(..).
The conditions are evaluated from left to right: if the first one is false, the others are not evaluated at all, because the && cannot be true anymore independent what the other conditions are.
if(collider != null && collider.equals(paddle)){
ballspeed = -ballspeed;
}
If you feel insecure about the evaluation order, you can also do the following:
if(collider != null){
if(collider.equals(paddle)){
ballspeed = -ballspeed;
}
}
Try this
if(collider != null && collider.equals(paddle) )
This should work.
Try changing the order of your second if statement to
if(collider != null && collider.equals(paddle))
If statements are evaluated left to right, if collider is null, the first statement will evaluate to false and the second statement won't be executed. Alternatively you could do something like
if(collider == null) {
//do nothing or attempt to get non null collider
}
else if(collider.equals(paddle))
{
ballspeed = -ballspeed;
}

Categories

Resources