Is this bad practice or any performance hit, this is to check x is not equal to null
if( !(x == null) ){
System.out.println("x is not a null value");
}
The normal way to do this is:
if(x != null){
System.out.println("x is not a null value");
}
There's nothing wrong with checking if the value is not null!
It is bad practice to do without making the reason to do so clear. It's not clear in your example why you are making the check. A common example might be something like
if (s == null || s.isEmpty()) // if s empty or not set.
or
if (s != null && s.length() > 0)
Usually, you do this when you need it in which case performance isn't important.
Normally you would write
if(x != null)
or better
if (x == null) {
// handle null, assuming this is not empty.
} else {
// handle not null
}
Performance-wise it is unlikely to be relevant, because you can trust the compiler to optimize that.
It's just a question of style. Style is always subjective, but I would say if (x != null) is more concise and more readable.
if(x != null) is recommended and easy to read "X is not equal to null"
if(!(x == null)) can't be read as "X is not equal to null"
Just to add here best practice is to do
if(null != x) {
System.out.println("x is not null");
}
instead of
if(x != null) {
System.out.println("x is not null");
}
I know in java anyways will work but this will save you in other languages like c++ where you might accidently assign null to x for example,
if(x = null) {
printf("x is not null");
}
if( !(x == null) ){
System.out.println("x is not a null value");
}
well if condition returns a boolean true of false. so, writing above will not effect anything. according, to above code the condition you wrote is "if is not true" then do something! and as others have suggested to write code as if(x != null) is better way and less confusing ;)
Related
I have a problem with the logic expression on my method matches1().
Problem
SonarQube is telling me there is an error:
(expectedGlobalRule == null && actual != null)
SonarQube:
Change this condition so that it does not always evaluate to
"true".
Conditions should not unconditionally evaluate to "TRUE" or to "FALSE"
I'm essentially doing this logic to avoid a NPE on my "Block to be executed".
My code
matches1()
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if((expected == null && actual != null) || (expected != null && actual == null)) {
return false;
} else {
//Block to be executed
}
}
I inverted the logic in to see what SonarQube would tell me and he doesn't complain about it.
matches2()
private boolean matches2(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(expected != null && actual != null) {
//Block to be executed
} else {
return false;
}
}
Question
Do the problem is in my boolean logic or it's SonarQube that lost
his mind?
If the problem is within sonarQube, how could I resolve it?
The problem is in your logic. Let's take it piece by piece:
if(actual == null && expected == null) {
return true;
At this point if both vars are null then we're no longer in the method. So if we get any further, then at least one of them is non-null.
The viable options at this point are:
actual = null, expected = non-null
actual = non-null, expected = null
actual = non-null, expected = non-null
Now, let's look at the next bit of code:
} else if((expected == null && actual != null)
We already know that both variables can't be null, so as soon as we know expected == null, there's no need to test whether actual != null. That has already been proven by the fact that we got this far. So actual != null is always true, which is why an issue is raised.
Edit
This means that your code could be boiled down to:
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(actual == null || expected == null) {
return false;
}
//Block to be executed
}
Note that the else isn't needed & dropping it makes the code easier to read.
Even when the code is correct; seriously, it makes my eyes hurt. Thing is: it is hard to read. Such kind of nested conditions is something that one should not be writing in the first place.
If you can't avoid it; at least refactor it into something like
private boolean areActualAnedExpectedBothNull(args ...) {
return actual == null && expectedGlobalRule == null;
}
And please note; you can dramatically simply your code:
if (areActualAnedExpectedBothNull(actual, expected)) {
return true;
}
if (actual == null) {
return false;
}
if (expected == null) {
return false;
}
do your thing ...
and use such methods in your other code. And of course, you do a lot of unit testing; probably with coverage measurements; just to make sure that your tests really test all possible paths through this maze.
But as said; you better step back and think if there are ways to avoid writing such code in the first place.
The typical answer to booleans, and if/else chains in OO programming is polymorphism. So instead of asking something about its state; you turn to interfaces/abstract classes; and have different implementations of those. And then you have a factory giving you that implementation you need; and then you just call methods on that; without further need for if/else/whatever.
If you don't know what I am talking about - watch these videos; especially the second one!
The problem is with SonarQube.
See this article for more info on ignoring that issue: https://www.bsi-software.com/en/scout-blog/article/ignore-issues-on-multiple-criteria-in-sonarqube.html
You can just set it up to ignore that error within that file.
The gist of it is
Open the Settings (SonarQube General Settings or project Settings) and
select the Exclusions category. Switch to the Issues Exclusions and
scroll down to “Ignore Issues on Multiple Criteria”. Set squid:S00112
as Rule Key Pattern and **/*Activator.java as File Path Pattern.
You will need to change the rule key pattern to the pattern associated with the rule that is being violated for your code and the file pattern as the path of your .java file.
I have a situation in my code where I make about 5 chained get calls, and any of those get calls could return a null value. I wish it didn't have to be that way, but that's just how the service I'm consuming returns the object I request, so I have to deal with it.
Originally, my code looked something like this:
String firstDomain = book.getBookImages().getDomains().getDefaults().getDomain().get(0);
Unfortunately, that line is prone to null pointers and arraylist out of bounds exceptions. I know I'm going to have to check for null pointers, but I'm trying to decide
A. The most efficient code to do so
and
B. The best looking code to do so
One option is to assign a ton of references and then check for nulls. Something like this:
BookImages bImages = book.getBookImages();
Domains domains = null;
Defaults defaults = null;
List<String> domain = null;
String firstDomain = null;
if (bImages != null) {
domains = bImages.getDomains();
if (domains != null) {
defaults = domains.getDefaults();
if (defaults != null) {
domain = defaults.getDomain();
if (domain != null && domain.size() > 0) {
firstDomain = domain.get(0);
}
}
}
}
if (firstDomain == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I think that's pretty efficient, but it bothers me how many lines it is. It more than doubles the length of the method it is a part of.
This is the other alternative I can think of:
if (book.getBookImages() == null || book.getBookImages().getDomains() == null || book.getBookImages().getDomains().getDefaults() == null || book.getBookImages().getDomains().getDefaults().getDomain() == null || book.getBookImages().getDomains().getDefaults().getDomain().size() < 1 || book.getBookImages().getDomains().getDefaults().getDomain().get(0) == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I like the fact that that's only three lines, even if one is pretty darn ridiculous, but I'm not sure if Java's runtime or compiler would optimize away those repetitive method calls.
I'm also open to other, better solutions. Does anyone know if one or the other of those options would perform better than the other, or is this such a micro-optimization that it's foolish to even bother thinking about it, and I should just use whichever looks nicer to me? I may have to do this many times for different things.
To follow your second approach, you can apply this:
if ((bImages=book.getBookImages()) == null
|| (domains=bImages.getDomains()) == null
|| (defaults=domains.getDefaults()) == null
|| (domain=defaults.getDomain()) == null
|| domain.size() < 1
|| (firstDomain=domain.get(0)) == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
} else {
//here you can use the firstDomain variable, that is set with the correct value
}
This is better because you avoid multiple (useless) identical calls, and you already set the correct value in the variable firstDomain (of course, only if there is nothing null and so on...)
As Szymon pointed out you should not call same method twice.
To make your original solution slightly more readable by combining all your nested null checks into one:
BookImages bImages = null;
Domains domains = null;
Defaults defaults = null;
List<String> domain = null;
String firstDomain = null;
if ((bImages = book.getBookImages()) != null
&& (domains = bImages.getDomains()) != null
&& (defaults = domains.getDefaults()) != null
&& (domain = defaults.getDomain() != null
&& domain.size() > 0) {
firstDomain = domain.get(0);
}
You should not worry about the length of the code too much if the longer code is correct and shorter incorrect. The goal of programming is not writing the shortest possible code (with the exception of some competitions, etc).
Your first (longer) way is correct, even if a bit longish.
The second way will make repeated calls to the same method. This is something you probably want to avoid - it may have undesirable effects and is worse for performance.
Try using a boolean method; they tend to make logic a lot simpler and much more legible; for example, I would do this:
public boolean isCompletelyAttributed(BookImages bImages) {
if (bImages == null) return false;
if (bImages.getDomains() == null) return false;
if (bImages.getDomains().getDefaults() == null) return false;
if (bImages.getDomains().getDefaults().getDomains() == null) return false;
return bImages.getDomains().getDefaults.getDomains.size() > 0;
}
Then you call
if (!isCompletelyAttributed(book.getImages())) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I also recommend that you use Nicola or kiruwka's solution in your boolean method. I was not aware that you could reassign variables while doing logic on them, but that appears to be an elegant solution.
Here's a short-ish way to do it. But hey, I don't know the specifics of what you're building and whether this works for you.
try {
String firstDomain = book.getBookImages().getDomains().getDefaults().getDomain().get(0);
// operate on firstDomain
} catch (NullPointerException e) {
throw new IncompleteBookException("The book was incompletely attributed.");
} catch (IndexOutOfBoundsException e) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I've heard that people are concerned with the performance of something like this, because the VM will have to fill in a stack trace for the NullPointerException. In this case, you'll already be doing a comparable operation for the IncompleteBookException anyway.
This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
What is the best way to avoid multiple if blocks which is used for null checks in Java?
The following is my sample code. Which one is the most optimized way?
if (address!=null} {
if (firstName!=null) {
if (lastName!=null) {
}
}
}
Use &&. && is logical and. && combines two values and returns a boolean which is true if and only if both of its operands are true
if(address!=null && firstName!=null && lastName!=null)
{
}
For instance
boolean b;
b = 3 > 2 && 5 < 7; // b is true
b = 2 > 3 && 5 < 7; // b is now false
if loop is a wrong word. You should say if statements As in you case you can use OR (||) or AND (&&)statement like this
if(address!=null && firstName!=null && lastName!=null)
{
}
Try AND(&&) if you want to pass all checks or intead of nested if statements and try OR(||) for non nested like else if or simply say if you want to pass anyone of your condition But
if all of these are Strings then you should try like this
"yourValue".equals(stringValue)This will skip the null check.
Use and operator (&&)
if(address!=null && firstName!=null && lastName!=null)
{
//DoSomething here
}
And I suggest you to see Short circuit evaluation
there are no if LOOPS
boolean complete = address != null && firstName != null && lastName != null;
if (complete)
{
}
What about:
public boolean notNulls(Object ... args) {
for(Object arg : args)
if (arg == null) return false;
return true;
}
Use:
if (notNulls(address, firstName, lastName)) {
// do something
}
As others point out, a logical and (&&) is probably the best way to consolidate your logic. An && operation will only evaluate to true if both sides evaluate to true.
if (address != null && firstName != null && lastName != null) {
// Whatever you want to do with that...
} else {
// Whatever you want to do with bad input
}
For the sake of diversity, you could also use a try-catch approach. In Java, a NullPointerException will be thrown if you try to call a method on a null value, which you can catch and handle.
try {
// Whatever you want to do with that...
} catch (NullPointerException npe) {
// Whatever you want to do with bad input
}
This approach can be helpful if you've got a really big set of inputs that might be null, although in general I wouldn't advocate it. (The problem with the second approach is that if you call some other method from the try part that triggers a NullPointerException, it will end up in the catch block here, even though it may be totally unrelated to these inputs - i.e. you could make it hard for yourself to spot a bug in a different part of your program.)
Here's the code
public void findDNode(String name)
{
DNode u = header;
while(u != null)
{
if(name == u.getElement())
{
System.out.println(u.getElement());
break;
}
else if (u == null)
{
System.out.println("Error: not found");
break;
}
u = u.nextNode();
}
}
For some reason when the node that I am looking for doesn't exist it's doesn't print the error: not found message.
edit: nevermind just realised when u== null the while loop won't happen
You should use equals() to compare Java strings:
if (name.equals(u.getElement()))
{
...
Comparing strings using the == operator compares the references, which in most cases isn't the right thing to do.
Also, the "not found" logic is misplaced. It should probably be placed outside the loop (with an appropriate if condition).
u never becomes null inside the loop! Perform the check after the loop.
public void findDNode(String name)
{
DNode u = header;
while(u != null)
{
if(name == u.getElement())
{
System.out.println(u.getElement());
break;
}
u = u.nextNode();
}
if (u==null)
System.out.println("Error: not found");
}
Edit: and yes, you should use equals()
Other than using equals() instead of == to compare String there is another issue.
How can you have if (u == null) inside a while(u != null) loop. That if (u == null) block will never execute since while loop will end when u == null. That is the reason Error: not found is never printed.
I use PMD to check my code. It gives me very useful hints in most cases, but I can't figure out what could be improved in the following scenario.
The original code looks something like this:
if ((getSomething() != null && getSomethingElse() != null)
|| (getSomething() == null && getSomethingElse() == null))
{
...
}
PMD tells me:
Sometimes two 'if' statements can be consolidated by separating their
conditions with a boolean short-circuit operator.
For simplicity, let's just use a and b as boolean variables. Then this piece of code looks like this:
if ((!a && !b) || (a && b))
This can be transformed to one of the following:
if ((!a || b) && (a || !b))
if (!(a^b))
and finally
if (a==b)
So I simplified my code to
if ((getSomething() == null) == (getSomethingElse() == null))
However, PMD keeps complaining (in fact about all three versions). Is this a false positive or is there a better way of writing the if-condition?
The problem was something different. The if-statement was the only code inside another if (the code comes from a validation-method):
if (...)
{
...
}
else if (...)
{
...
}
else if (...)
{
if ((getSomething() == null) == (getSomethingElse() == null))
{
...
}
}
What the PMD-message means, is that I could combine the conditions of the last else-if and the inner if-clause:
if (...)
{
...
}
else if (...)
{
...
}
else if (... && ((getSomething() == null) == (getSomethingElse() == null)))
{
...
}
However, I'm not sure, if I'll do this, because the original version seems much clearer to understand.
if ((a != null) && (b != null) && (a==b))
..although personally, I'd do the null checking prior to this if statement so I could handle the a == null and b == null cases individually
The issue is that large blocks of conditionals are difficult to reason about.
OTOH, not every warning PMD emits needs to be paid attention to--consider the ROI. Is it worth refactoring or restructuring to make it cleaner? Can the same functionality be handled in a different way?
If it's not worth it, don't bother.