I just was tidying my code a bit and there was this piece:
String saving = getValue();
if(saving != null && saving.equals(\"true\")){
// do someth
if("true".equals(saving)){
// do something
}
This is very safe and good practice. String "true" will never be null. So you will never compare your String to null. This piece of code is perfectly fine
Sorry but I cannot agree on that issue.
If you use the constant first you support structures that veil programming errors. And one should only produce code either
On top you have a weak assertion about the variable. Following code is always forced to check for null values as well.
If you have to deal with null values from other modules your task is to map them into proper representations in your domain model as early as possible.
In your own code avoid null as parameter or return value, so there won't be any null-checks neccessary anymore, the suggested piece of code included.
You see, this subject is more about avoiding null than accepting it to conquer your code.
if ("true".equals(saving))
is perfectly "save" and recommended by dummy product as SonarLint and any other advisors that establish this "well" thinked rule that your chief request that you follow.
I say stupid and my explanation is the following.
What happens if you have following code
if (!saving.equals("true"))
{
if (saving.length() > 10)
{
// do something
}
}
You can use following advised code
if (!"true".equals(saving))
{
if (saving.length() > 10)
{
// do something
}
}
But when your code is deployed on production, the program will crash on length()
function if saving variable has not been initialized and contains NULL.
You have changing your code to avoid NullPointerException
on equals()
function but your program will return another NullPointerException
on length()
function !
The good reaction is to stop to use String literal tip and to analyze code to find a perfect solution as in the following example.
if (saving != null)
{
if (!saving.equals("true"))
{
if (saving.length() > 10)
{
// do something
}
}
}
or
if (saving == null) saving = "";
if (!saving.equals("true"))
{
if (saving.length() > 10)
{
// do something
}
}
Is is perhaps verbose but if you will use Java for programming it is the price to pay.
Using String literal equals() method to avoid NullPointerException
has the following disadvantages
I disagree with some of the answers. Sometimes you do want to know if your variable is null
. It might be an indication that something is bad happening in your code and you might want to reconsider your logic.
I don't like to do if("someString".equals(myString));
because I do want to know if myString
is null
and maybe handle it or change my logic to prevent situations like this.
Imagine you have an array of Objects that was miscalculated due to some bug:
myStrings = {..., ..., null, null, ...};
Then you want to perform some operations on the objects of the array, and you'll have:
if("myString".equals(myObjArray[i])) { ... }
You won't get NullPointerException
and you'll think that you performed the operation on all the objects in the array.. And you'll never know that you miscalculated it because you "hided" the exception. Whereas if you did:
if(myObjArray[i].equals("myString")) { ... }
You'll get a NPE and you'll know something is wrong in the array.. and you might want to fix this or handle it in another way.
Just to ensure there is a fully balanced set of answers to this question I would like to post a different opinion.
I think this mechanism is foolish.
If you have a null
you should know as soon as it happens - hiding it will just postpone its discovery. If the null
is not an exception, replace it with something else.
Taking this approach will fortify your code with what is called defensive programming where your mistakes are discovered as soon as possible rather than covered up until everything falls apart.
In summary - NullPointerException
is your friend. You should use it to find mistakes in your code. It is very easy to use a Empty object such as Collections.emptySet()
once you have determined that the null
is not an exception.
Using the Yoda technique out of habit will inevitably hide errors you do not mean to hide. Not using it will expose errors much earlier. To me that is sufficient argument to not use it - ever.
To me - using
if(saving != null && saving.equals("true")){
means that I actually want to allow savings
to be null
and it is an acceptable situation - using
if("true".equals(saving)){
merely hides that deliberate choice in a way that could become a bad habit.
It's called yoda conditions (putting a constant before a variable in a comparison) can be considered like bad practise, maybe for someone much less readable (like me).
But sometimes using yoda condition makes the code more "comprehensible" ->
you don't need to put extra null check in front of it and it efficiently differentiates block of code from case where null is strongly forbidden.