Is this a good IF block? - java

Are these comparisons always safe from creating a NullPointer Exception ?
if( myObject == null || myObject.someMethod() == someValue )
{
if( myObject == null && myObject.getAlwaysTrue() )
{
}
}
Is there some directional precedence in java for condition evaluation, apart from short circuiting ?
UPDATE: I Know myObject.anything() will throw a NullPointer. Its just that I have come across such code by other programmers, and I want to know if there's a safe way of squeezing multiple checks along with a null check in a single condition. I'm looking for a good rule to stick to.

No, this line is not safe:
if( myObject == null && myObject.getAlwaysTrue() )
If you know that myObject is null then you shouldn't try to dereference it. If however you wrote this:
if( myObject != null && myObject.getAlwaysTrue() )
Then it would be safe. This is because && (and || for that matter) has short-circuit evaluation. If you write a && b and the expression a evaluates to false, then the expression b is not evaluated so it will not throw an exception. The left operand is always evaluated first.

Why not separate out the gating issue?
if (myObject != null) {
if ((myObject.someMethod() == someValue) && myObject.getAlwaysTrue()) {
}
}

if( myObject == null && myObject.getAlwaysTrue() )
This will cause you a NullPointerException when myObject is null

Wherever I can, I strive for less indentantion and complex "ifology". In your case I'd just write
if (myObject == null) return;
... go on knowing that myObject is not null...

If the myObject is null, myObject.getAlwaysTrue() in the second if statement will always result in NullPointerException.
In the case of || the if expression evaluates the boolean expressions until it finds the first one that's true.
With && the if expression evaluates the boolean expressions until it finds the first one that's false.
So in your case when myObject is null, you'll get the following evaluations:
First if:
myObject == null -> true
Second if:
myObject == null -> true
myObject.getAlwaysTrue() -> NullPointerException

This is not :
if( myObject == null && myObject.getAlwaysTrue() )
&& will check both conditions, myObject.getAlwaysTrue() will throw NullPointerException if myObject is null.

Related

How to compare an Integer using least code?

There is an Integer property called foo in a model. Now I need to know whether it equals 1 or 2. Usually I use:
if (null != model) {
Integer foo = model.getFoo();
if (foo != null) {
if (foo == 1) {
// do something...
}
if (foo == 2) {
// do something...
}
}
}
Is there any handier code to avoid the NullPointerException?
You can use Optional:
Optional.ofNullable(model)
.map(Model::getFoo)
.ifPresent(foo -> {
switch (foo) { // or if-else-if, the important thing is you skip the null check
case 1:
...
break;
case 2:
...
break;
...
}
});
You can use the null-safe java.util.Object.equals:
if(null != model) {
Integer foo = model.getFoo();
if(Objects.equals(foo, 1){
//do something
}
if(Objects.equals(foo, 2){
//do something
}
}
The method has this description:
Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument.
If you didn't return null sentinels values, and instead used Optionals, you could do:
Optional<Model> model = getModel();
Optional<Integer> foo = model.flatMap(Model::getFoo);
foo.filter(Integer.valueOf(1)::equals).ifPresent(this::doSomething);
foo.filter(Integer.valueOf(2)::equals).ifPresent(this::doSomethingElse);
You could do Integer.of(1).equals(foo), but this is a bit silly. Why save the one line? I'd just put it inside the same if/else-if chain (and if that gets long, conside a switch/case (which also is not null-safe, though).
if (foo == null)
else if (foo == 1)
else if (foo == 2)
Also note that comparing objects with == is a bit tricky because of how auto-boxing works (or does not work). I think that it works in this case, but I do not want to have to think about it too hard, so in my code I usually drop down to int (after the null check) to be on the safe side.
Assuming possible value is only 1 or 2
Of course the model the should be guarded with null check
Use ternary operator
Model theModel = model.getFoo() ;
if(model!=null && model.getFoo()!=null){
model.getFoo() == 1 ? callOne() : call2();
}
Edit the code to like this:
if (null != model) {
Integer foo = model.getFoo();
if (Integer.valueOf(1).equals(foo)) {
// do something...
}
if (Integer.valueOf(2).equals(foo)) {
// do something...
}
}
I hope to help you.

How to prevent the error: null > 0 java

I currently have an enumlist. The enumlist gets filled at random, so there is a possibility that one has the value null. That is logical because it doesn't get filled.
The problem is further in my code I have:
if (player.Enumlist().get(CART_BLACK) > 0) {
}
Java throws a NullPointerException. Is there something I could add to the if-statement to prevent this error?
If get(CART_BLACK) may return null:
Get the value before the condition and replace it with a negative value if it's null:
Integer cartBlack = player.Enumlist().get(CART_BLACK);
if (cartBlack == null) cartBlack = -1;
if (cartBlack > 0) {
If player.Enumlist() may return null
Similar, but not quite identical:
final Enumlist list = player.Enumlist();
final int cartBlack = list == null ? -1 : list.get(CART_BLACK);
if (cartBlack > 0) {
You'll need to guard against nullity:
if(player.Enumlist().get(CART_BLACK) != null &&
player.Enumlist().get(CART_BLACK) > 0) {...}
or a more efficient version:
Integer temp = player.Enumlist().get(CART_BLACK);
if (temp != null && temp > 0){...}
if( player.Enumlist().get(CART_BLACK) != null && player.Enumlist().get(CART_BLACK) > 0) {
}
This will work because ifs are checked from left to right, and if one condition fails the rest won't be evaluated and you won't get the NPE.
Correcting the issue at the end makes the trick but it is not fine because it means that it may occur in other invocations. Besides, as a consequence, you may finish by overusing not null guards as you will never know if the null is a normal case.
So you should favor the use of Optional (Java 8 or Guava) as return rather than null to make your API clearer (it may return an empty thing so convey that) and more robust (the contained object has to be specifically unwrapped).
For example :
Optional<Integer> optValue = player.Enumlist().get(CART_BLACK);
optValue.filter(v -> v > 0)
.ifPresent( v -> ...);
You need to do Null Checking:
if (player == null || player.Enumlist () == null) {
throw new Exception("Player or Enumlist cannot be null");
}
You should also check that the Integer value is not null, but I guess that would be pretty weird if you wrote the code.
You are using get which could give you an IndexOutOfBoundsException eventually. You could check that using the size method or using streams.
If (player.Enumlist().size() > CART_BLACK && player.Enumlist().get(CART_BLACK) != null && player.Enumlist().get(CART_BLACK) > 0) {
//...
}
You may check for Null also handle the exception using try..catch block
try
{
if( player.Enumlist().get(CART_BLACK)!=null && player.Enumlist().get(CART_BLACK) > 0)
{
}
}
catch(NullPointerException)
{
//handle exception here
}

Ternary operator evaluating conditional statement while condition not met

I have written some code; here the relevant snippets:
#NonNullByDefault
public class Score<NUMERAL, LITERAL>
{
protected NUMERAL value;
#Nullable
protected LITERAL literal;
[...]
I have overwritten my equals()method as follows:
#Override
public boolean equals(#Nullable Object object)
{
if(object == null) return false;
if(object == this) return true;
if( object instanceof Score)
{
return ((Score<NUMERAL, LITERAL>) object).getValue().equals(value) &&
literal == null ? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null : literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral());
}
return false;
}
Basically, the idea is that a Score may only have a numeric value in which case the literal is null. I have written some unit tests and get a null pointer exception with the code below:
[....]
Score<Float, String> score = new Score<>(0.0f);
Score<Float, String> anotherScore = new Score<>(1.0f, "One");
[....]
assertFalse(score.equals(anotherScore));
If I am not mistaken, shouldn't short-cutting in equals prevent anything after the && from being executed as the first expression is already false? Furthermore, why the exception? As the conditional is true, I would expect the expression of the ternary to be evaluated and the conditional expression skipped. From what I have read in the specifications, this should be the behaviour. Furthermore, I found this question: Java ternary (immediate if) evaluation which should lend some more leverage to my thought process.
Maybe I have overlooked something rather obvious but I am out of ideas. Maybe you can help?
It short-circuits alright, but not quite the way you want it to. && has a higher precedence than the ternary ?: - therefore this (indentation, line breaks and comments added to clarify)
((Score<NUMERAL, LITERAL>) object).getValue().equals(value) &&
literal == null
? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null
: literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral())
actually means this:
//the first line as a whole is the condition for ?:
((Score<NUMERAL, LITERAL>) object).getValue().equals(value) && literal == null
? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null
: literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral())
This means, in practice, that if the first part of the condition is false but literal is null, you automatically enter the : part of the expression where you call literal.equals, causing the NullPointerException.
The fix is simple: add parentheses to tell Java which way you want stuff to be evaluated:
((Score<NUMERAL, LITERAL>) object).getValue().equals(value) &&
(literal == null
? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null
: literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral()))

Confuse "==null" and "==" "" in java?

I have a simple issue related ==null and =="" ,i think everybody know this issue .
Here's an example:
#SuppressWarnings("unchecked")
public void reorderingCriteia() {
ListModelList<ReorderData> headerList = new ListModelList<ReorderData>();
List<String> headerId = new ArrayList<String>();
String userReorderSelection = Services.userPreferenceService().getUserPreference().getUserOption("PROCESS_CHECKLIST_COLUMN_REORDER");
if (userReorderSelection == null || userReorderSelection == "") {
int i = 0;
for (ReorderData rd : availableReorderList) {
headerList.add(rd);
headerId.add("" + i);
i++;
}
folderProcessModel.setHeaderList(headerList);
folderProcessModel.setHeaderId(headerId);
} else {
headerList = ReorderDialogViewModelNew.jsonStringToList("FOLDER_PERMIT_LIST_COLUMN_REORDER", userReorderSelection, false);
headerId = compHelper.intializeSequnce(headerList, folderProcessModel.getAvailableHeaders());
folderProcessModel.setHeaderList(headerList);
folderProcessModel.setHeaderId(headerId);
}
}
I have some questions:
Here this code use if (userReorderSelection == null || userReorderSelection == ""). Can i use this condition if (userReorderSelection == null) ?
What is the difference between two ?
== null checks for null reference.
== "" check for blank/empty string reference. Here you could use str.equals("") to check if the string is empty/blank or not. == is used for object reference checks. Or you can use the String.isEmpty() to check the same.
Also, if you use just if (userReorderSelection == null), then you'll only be checking if the userReorderSelection is null or not and it won't determine whether the String is empty or not.
As everyone replied:
"" checks for empty String.
null checks for null reference.
Use StringUtils from apache commons to eliminate two conditions. StringUtils.isEmpty(yourVariable) this condition will handle both cases.
"" --> indicates empty String in Java. Rather than using userReorderSelection == "" it is preferable to us
userReorderSelection.isEmpty() // But make sure that userReorderSelection is not null
null --> indicates Null references (can be reference of any object)
If you do not have this check it may result in NullPointerException if you try to use this reference. Empty String will not throw such exceptions.
== null checks to see if the object reference is null.
== "" checks to see if the object reference equals a blank string
str.equals ("") checks to see if your String object contains the empty string.
I guess what you want is
if (userReorderSelection == null || userReorderSelection.equals (""))

Equality comparison -- any saner way?

How do I implement this equality comparison is a sane java way?
boolean x = (a == b) || (a.equals(b))
I want to make sure the content of both objects is equal but null is also ok, i.e. both can be null and are thus equal.
Update: just to be clear, I have to implement this comparison several times and don't want to copy&paste this stuff every time, especially with lenghty object names. With 'a' and 'b' it looks small and simple, but tends to grow... I'd like to know if I'm missing some existing Java feature for this.
You might want to have a look at the always useful Apache Commons Lang, more precisely ObjectUtils.equals().
Another way to do
boolean x = null==a ? null==b : a.equals(b);
The typical pattern is:
if (a == b)
{
return true;
}
if (a == null || b == null)
{
return false;
}
// Now deal with a and b, knowing that they are non-identical, non-null references
Yes, it's wordy - but if you separate it out into its own method, you can keep it under reasonable control.
What happens if a is null but b is not? I think you really want:
boolean x = (a == null && b == null) || (a != null && a.equals(b))
EDIT: You could implement a static NullEquals method for the class that takes two objects of that class and does the comparison as above to avoid rewriting and make the code a little cleaner.
public class MyClass {
public static boolean NullEquals( MyClass a, MyClass b )
{
return (a == null && b == null) || (a != null && a.equals(b));
}
}
if (MyClass.NullEquals(a,b))
{
...
}
Not a direct answer, but if you have lot of objects that can be or not null, may be that indicates some problem with your code. Take a look at the Null Pattern , that is an alternative way to represent the absence of an object
What about:
boolean x = equals( a, b );
public static boolean equals( Object a, Object b ) {
if ( a == null && a == b ) {
return true;
} else {
return a == b || a.equals( b );
}
}
Let me see.
if a is null and a is b then it's ok
if a is not null then if a == b ( same ref ) return true by shortcircuit
if a is not b ( 2dns part of the OR probably b is null ) then return a ( not null ) .equals( b ) whatever b is
Yeap covered.
Can not add comment,
Treat this as comment to Jon Skeet's answer.
Does Null = Null true or false in Java.
More specifically what should be Null = Null should be treated and How and why the different language treat this case ?
The most common way of doing it is:
a==null ? b==null : a.equals(b)
A potentially slightly more efficient, but less clear, expressions is:
a==b || (a!=null && a.equals(b))
You can of course put this inside a method:
public static boolean eq(Object a, Object b) {
return a==b || (a!=null && a.equals(b));
}
Note the original question code NPEs if a is null and b is non-null.
For performance reasons, usually it is good to check for identity before executing any other logic, as was done in the question. However, many of the answers don't take this into account.
The best place to put the identity check is in the implementation of the equals method on your class:
public boolean equals(Object obj) {
if(this == obj) return true;
...
}
If this has/can be done, you can do the comparison easily:
a == null ? b == null : a.equals(b);
Otherwise you might have to check for identity yourself:
a == null ? b == null : (a == b || a.equals(b));

Categories

Resources