Variable referencing vs. repetitive get calls to avoid null pointers - java

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.

Related

Better condition in java for conditional code [duplicate]

I used spring boot to develop a shell project used to send email, e.g.
sendmail -from foo#bar.com -password foobar -subject "hello world" -to aaa#bbb.com
If the from and password arguments are missing, I use a default sender and password, e.g. noreply#bar.com and 123456.
So if the user passes the from argument they must also pass the password argument and vice versa. That is to say, either both are non-null, or both are null.
How do I check this elegantly?
Now my way is
if ((from != null && password == null) || (from == null && password != null)) {
throw new RuntimeException("from and password either both exist or both not exist");
}
There is a way using the ^ (XOR) operator:
if (from == null ^ password == null) {
// Use RuntimeException if you need to
throw new IllegalArgumentException("message");
}
The if condition will be true if only one variable is null.
But I think usually it's better to use two if conditions with different exception messages. You can't define what went wrong using a single condition.
if ((from == null) && (password != null)) {
throw new IllegalArgumentException("If from is null, password must be null");
}
if ((from != null) && (password == null)) {
throw new IllegalArgumentException("If from is not null, password must not be null");
}
It is more readable and is much easier to understand, and it only takes a little extra typing.
Well, it sounds like you're trying to check whether the "nullity" condition of the two is the same or not. You could use:
if ((from == null) != (password == null))
{
...
}
Or make it more explicit with helper variables:
boolean gotFrom = from != null;
boolean gotPassword = password != null;
if (gotFrom != gotPassword)
{
...
}
Personally, I prefer readable to elegant.
if (from != null && password == null) {
throw new RuntimeException("-from given without -password");
}
if (from == null && password != null) {
throw new RuntimeException("-password given without -from");
}
Put that functionality in a 2 argument method with the signature:
void assertBothNullOrBothNotNull(Object a, Object b) throws RuntimeException
This saves space in the actual method you are interested in and makes it more readable. There is nothing wrong with slightly verbose method names and there is nothing wrong with very short methods.
A Java 8 solution would be to use Objects.isNull(Object), assuming a static import:
if (isNull(from) != isNull(password)) {
throw ...;
}
For Java < 8 (or if you don't like using Objects.isNull()), you can easily write your own isNull() method.
Here is a general solution for any number of null checks
public static int nulls(Object... objs)
{
int n = 0;
for(Object obj : objs) if(obj == null) n++;
return n;
}
public static void main (String[] args) throws java.lang.Exception
{
String a = null;
String b = "";
String c = "Test";
System.out.println (" "+nulls(a,b,c));
}
Uses
// equivalent to (a==null & !(b==null|c==null) | .. | c==null & !(a==null|b==null))
if (nulls(a,b,c) == 1) { .. }
// equivalent to (a==null | b==null | c==null)
if (nulls(a,b,c) >= 1) { .. }
// equivalent to (a!=null | b!=null | c!=null)
if (nulls(a,b,c) < 3) { .. }
// equivalent to (a==null & b==null & c==null)
if (nulls(a,b,c) == 3) { .. }
// equivalent to (a!=null & b!=null & c!=null)
if (nulls(a,b,c) == 0) { .. }
Since you want to do something special (use defaults) when both sender and password are absent, handle that first.
After that, you should have both a sender and a password to send an e-mail; throw an exception if either is missing.
// use defaults if neither is provided
if ((from == null) && (password == null)) {
from = DEFAULT_SENDER;
password = DEFAULT_PASSWORD;
}
// we should have a sender and a password now
if (from == null) {
throw new MissingSenderException();
}
if (password == null) {
throw new MissingPasswordException();
}
An added benefit is that, should either of your defaults be null, that will be detected as well.
Having said that, in general I think that use of XOR should be permissible when that is the operator you need. It is a part of the language, not just some trick that works because of an arcane compiler-bug.
I once had a cow-orker who found the ternary operator too confusing to use...
I would like to suggest another alternative which is how I would actually write this piece of code:
if( from != null )
{
if( password == null )
error( "password required for " + from );
}
else
{
if( password != null )
warn( "the given password will not be used" );
}
To me this seems to be the most natural way to express this condition which makes it easy to understand for somebody who might have to read it in the future. It also allows you to give more helpful diagnostic messages and treat the unnecessary password as less serious and it makes it easy to modify which is rather likely for such a condition. I.e. you may find out that giving a password as a command line argument is not the best idea and may want allow reading the password from standard input optionally if the argument is missing. Or you may want to silently ignore the superfluous password argument. Changes like these would not require you to rewrite the whole thing.
Besides that it executes only the minimum number of comparisons, so it's not more expensive than the more "elegant" alternatives. Although performance is very unlikely a problem here because starting a new process is already much more expensive than a extra null check.
I think a correct way to handle this is to consider three situations: both 'from' and 'password' are provided, neither are provided, a mix of the two are provided.
if(from != null && password != null){
//use the provided values
} else if(from == null && password == null){
//both values are null use the default values
} else{
//throw an exception because the input is not correct.
}
It sounds like the original question wants to break the flow if it is incorrect input, but then they will have to repeat some of the logic later. Perhaps a good throw statement might be:
throw new IllegalArgumentException("form of " + form +
" cannot be used with a "
+ (password==null?"null":"not null") +
" password. Either provide a value for both, or no value for both"
);
Here's a relatively straight-forward way that does not involve any Xor og lengthy ifs. It does however require you to be slightly more verbose, but on the upside, you can use the custom Exceptions I suggested to get a more meaningful error message.
private void validatePasswordExists(Parameters params) {
if (!params.hasKey("password")){
throw new PasswordMissingException("Password missing");
}
}
private void validateFromExists(Parameters params) {
if (!params.hasKey("from")){
throw new FromEmailMissingException("From-email missing");
}
}
private void validateParams(Parameters params) {
if (params.hasKey("from") || params.hasKey("password")){
validateFromExists(params);
validatePasswordExists(params);
}
}
Nobody seems to have mentioned the ternary operator:
if (a==null? b!=null:b==null)
Works nicely for checking this particular condition, but doesn't generalize well past two variables.
As I see your intentions, there is no need to always check both exclusive nullities but to check if password is null if and only if from is not null. You can ignore the given password argument and use your own default if from is null.
Written in pseudo must be like this:
if (from == null) { // form is null, ignore given password here
// use your own defaults
} else if (password == null) { // form is given but password is not
// throw exception
} else { // both arguments are given
// use given arguments
}
I'm surprised nobody mentioned the simple solution of making from and password fields of a class and passing a reference to an instance of that class:
class Account {
final String name, password;
Account(String name, String password) {
this.name = Objects.requireNonNull(name, "name");
this.password = Objects.requireNonNull(password, "password");
}
}
// the code that requires an account
Account from;
// do stuff
Here from could be null or non-null and if it's non-null, both its fields have non-null values.
One advantage of this approach is that the error of making one field but not the other field null gets triggered where the account is initially obtained, not when the code using the account runs. By the time the code using the account is executed, it's impossible for the data to be invalid.
Another advantage to this approach is more readable as it provides more semantic information. Also, it's likely that you require the name and password together in other places so the cost of defining an additional class amortizes over multiple usages.
if ((from == null) == (password == null)){ //if both are true or both are false
}
(Source: Intellij IDEA)

SonarQube - boolean logic correctness -

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.

Check two arguments in Java, either both not null or both null elegantly

I used spring boot to develop a shell project used to send email, e.g.
sendmail -from foo#bar.com -password foobar -subject "hello world" -to aaa#bbb.com
If the from and password arguments are missing, I use a default sender and password, e.g. noreply#bar.com and 123456.
So if the user passes the from argument they must also pass the password argument and vice versa. That is to say, either both are non-null, or both are null.
How do I check this elegantly?
Now my way is
if ((from != null && password == null) || (from == null && password != null)) {
throw new RuntimeException("from and password either both exist or both not exist");
}
There is a way using the ^ (XOR) operator:
if (from == null ^ password == null) {
// Use RuntimeException if you need to
throw new IllegalArgumentException("message");
}
The if condition will be true if only one variable is null.
But I think usually it's better to use two if conditions with different exception messages. You can't define what went wrong using a single condition.
if ((from == null) && (password != null)) {
throw new IllegalArgumentException("If from is null, password must be null");
}
if ((from != null) && (password == null)) {
throw new IllegalArgumentException("If from is not null, password must not be null");
}
It is more readable and is much easier to understand, and it only takes a little extra typing.
Well, it sounds like you're trying to check whether the "nullity" condition of the two is the same or not. You could use:
if ((from == null) != (password == null))
{
...
}
Or make it more explicit with helper variables:
boolean gotFrom = from != null;
boolean gotPassword = password != null;
if (gotFrom != gotPassword)
{
...
}
Personally, I prefer readable to elegant.
if (from != null && password == null) {
throw new RuntimeException("-from given without -password");
}
if (from == null && password != null) {
throw new RuntimeException("-password given without -from");
}
Put that functionality in a 2 argument method with the signature:
void assertBothNullOrBothNotNull(Object a, Object b) throws RuntimeException
This saves space in the actual method you are interested in and makes it more readable. There is nothing wrong with slightly verbose method names and there is nothing wrong with very short methods.
A Java 8 solution would be to use Objects.isNull(Object), assuming a static import:
if (isNull(from) != isNull(password)) {
throw ...;
}
For Java < 8 (or if you don't like using Objects.isNull()), you can easily write your own isNull() method.
Here is a general solution for any number of null checks
public static int nulls(Object... objs)
{
int n = 0;
for(Object obj : objs) if(obj == null) n++;
return n;
}
public static void main (String[] args) throws java.lang.Exception
{
String a = null;
String b = "";
String c = "Test";
System.out.println (" "+nulls(a,b,c));
}
Uses
// equivalent to (a==null & !(b==null|c==null) | .. | c==null & !(a==null|b==null))
if (nulls(a,b,c) == 1) { .. }
// equivalent to (a==null | b==null | c==null)
if (nulls(a,b,c) >= 1) { .. }
// equivalent to (a!=null | b!=null | c!=null)
if (nulls(a,b,c) < 3) { .. }
// equivalent to (a==null & b==null & c==null)
if (nulls(a,b,c) == 3) { .. }
// equivalent to (a!=null & b!=null & c!=null)
if (nulls(a,b,c) == 0) { .. }
Since you want to do something special (use defaults) when both sender and password are absent, handle that first.
After that, you should have both a sender and a password to send an e-mail; throw an exception if either is missing.
// use defaults if neither is provided
if ((from == null) && (password == null)) {
from = DEFAULT_SENDER;
password = DEFAULT_PASSWORD;
}
// we should have a sender and a password now
if (from == null) {
throw new MissingSenderException();
}
if (password == null) {
throw new MissingPasswordException();
}
An added benefit is that, should either of your defaults be null, that will be detected as well.
Having said that, in general I think that use of XOR should be permissible when that is the operator you need. It is a part of the language, not just some trick that works because of an arcane compiler-bug.
I once had a cow-orker who found the ternary operator too confusing to use...
I would like to suggest another alternative which is how I would actually write this piece of code:
if( from != null )
{
if( password == null )
error( "password required for " + from );
}
else
{
if( password != null )
warn( "the given password will not be used" );
}
To me this seems to be the most natural way to express this condition which makes it easy to understand for somebody who might have to read it in the future. It also allows you to give more helpful diagnostic messages and treat the unnecessary password as less serious and it makes it easy to modify which is rather likely for such a condition. I.e. you may find out that giving a password as a command line argument is not the best idea and may want allow reading the password from standard input optionally if the argument is missing. Or you may want to silently ignore the superfluous password argument. Changes like these would not require you to rewrite the whole thing.
Besides that it executes only the minimum number of comparisons, so it's not more expensive than the more "elegant" alternatives. Although performance is very unlikely a problem here because starting a new process is already much more expensive than a extra null check.
I think a correct way to handle this is to consider three situations: both 'from' and 'password' are provided, neither are provided, a mix of the two are provided.
if(from != null && password != null){
//use the provided values
} else if(from == null && password == null){
//both values are null use the default values
} else{
//throw an exception because the input is not correct.
}
It sounds like the original question wants to break the flow if it is incorrect input, but then they will have to repeat some of the logic later. Perhaps a good throw statement might be:
throw new IllegalArgumentException("form of " + form +
" cannot be used with a "
+ (password==null?"null":"not null") +
" password. Either provide a value for both, or no value for both"
);
Here's a relatively straight-forward way that does not involve any Xor og lengthy ifs. It does however require you to be slightly more verbose, but on the upside, you can use the custom Exceptions I suggested to get a more meaningful error message.
private void validatePasswordExists(Parameters params) {
if (!params.hasKey("password")){
throw new PasswordMissingException("Password missing");
}
}
private void validateFromExists(Parameters params) {
if (!params.hasKey("from")){
throw new FromEmailMissingException("From-email missing");
}
}
private void validateParams(Parameters params) {
if (params.hasKey("from") || params.hasKey("password")){
validateFromExists(params);
validatePasswordExists(params);
}
}
Nobody seems to have mentioned the ternary operator:
if (a==null? b!=null:b==null)
Works nicely for checking this particular condition, but doesn't generalize well past two variables.
As I see your intentions, there is no need to always check both exclusive nullities but to check if password is null if and only if from is not null. You can ignore the given password argument and use your own default if from is null.
Written in pseudo must be like this:
if (from == null) { // form is null, ignore given password here
// use your own defaults
} else if (password == null) { // form is given but password is not
// throw exception
} else { // both arguments are given
// use given arguments
}
I'm surprised nobody mentioned the simple solution of making from and password fields of a class and passing a reference to an instance of that class:
class Account {
final String name, password;
Account(String name, String password) {
this.name = Objects.requireNonNull(name, "name");
this.password = Objects.requireNonNull(password, "password");
}
}
// the code that requires an account
Account from;
// do stuff
Here from could be null or non-null and if it's non-null, both its fields have non-null values.
One advantage of this approach is that the error of making one field but not the other field null gets triggered where the account is initially obtained, not when the code using the account runs. By the time the code using the account is executed, it's impossible for the data to be invalid.
Another advantage to this approach is more readable as it provides more semantic information. Also, it's likely that you require the name and password together in other places so the cost of defining an additional class amortizes over multiple usages.
if ((from == null) == (password == null)){ //if both are true or both are false
}
(Source: Intellij IDEA)

Best practice : get deep value of an object

Often in java I have to get a value of a property of an object which is deep in this object. For example, if I'm sure that all my sub-objects are not null, I can do that :
public function getDeepValue(A a) {
String value = a.getB().getC().getListeD().get(0).getE().getValue();
return value;
}
But in case of sub objects of the parent can be null, I have to test every object.
To do that, I see 2/3 solutions :
First, step by step :
public function getDeepValue(A a) {
if(a == null){
return null;
}
B b = a.getB();
if(b == null) {
return null;
}
C c = b.getC();
if(c == null){
return null;
}
List<D> ds = c.getListeD();
if(ds == null || ds.size() == 0){
return null;
}
D d = ds.get(0);
if(d == null) {
return null;
}
E e = d.getE()
if(e == null){
return null;
}
return e.getValue();
}
Second, test all in one if block, soooo dirty :
public function getDeepValue(A a) {
if(a != null && a.getB() != null && a.getB().getC() != null && a.getB().getC().getListeD() != null && a.getB().getC().getListeD().size() > 0 && a.getB().getC().getListeD().get(0) != null && a.getB().getC().getListeD().get(0).getE() != null){
return a.getB().getC().getListeD().get(0).getE().getValue();
}
return null;
}
Third solution, using a try catch block :
public function getDeepValue(A a) {
try {
return a.getB().getC().getListeD().get(0).getE().getValue();
} catch(NullPointerException e) {
return null;
} catch(IndexOutOfBoundsException e) {
return null;
}
}
Solution 1 seems not too bad but needs a lot of code. It is generally the solution I use.
Solution 2 is for me really dirty...
In paper, I realy like solution 3, but is it a good solution in term of performances ?
Is there any others acceptables solutions ?
Thanks for help, I hope my english is not too bad..
Regards
Solution #3 looks simple, but it can potentially hide a whole host of problems. It might be an adequate solution if you have full access to all of the classes in the chain and you know what's going on in each method and you can guarantee those methods won't cause problems with your try/catch and you're never going to change them... that's a lot of conditions to make it a worthwhile solution, but I can conceive that it's possibly a useful sufficient one.
Solution #2 looks horrid to me, especially if one or more of the get methods is a bottleneck (such as a slow database query or using a blocking network connection). The earlier in the chain such a potential bottleneck, the worse it would potentially be, as you're calling it over and over again. This of course depends on the implementation of the methods in question (even if one of them is slow, the result could be cached, for example), but you shouldn't need to know that in your client code. Even with efficient or trivial implementations, you've still got the overhead of repeated method calls you oughtn't need.
Solution #1 is the best of the three, but it's likely not the best possible. This solution takes more lines of code than the other two, but it doesn't repeat itself and it isn't going to be tripped up by the implementations of the other methods. (Note: If you do not have access to the classes in the chain for refactoring, I would use this solution.)
A better solution than #1 would be to refactor the classes so that the client code doesn't need to know about this chain at all. Something along these lines:
class Client {
public Mumble getDeepValue(A a) { return a == null ? null : a.getDeepValue(); }
}
class A {
private B b;
public Mumble getDeepValue() { return b == null ? null : b.getDeepValue(); }
}
class B {
private C c;
public Mumble getDeepValue() { return c == null ? null : c.getDeepValue(); }
}
class C {
private List<D> ds;
public Mumble getDeepValue() {
D d = ds == null || ds.size() == 0 ? null : ds.get(0);
return d == null ? null : d.getDeepValue();
}
}
class D {
private E e;
public Mumble getDeepValue() { return e == null ? null : e.getMumble(); }
}
class E {
private Mumble m;
public Mumble getMumble() { return m; }
}
As you can see, the longest chain any of these classes has is to access the public members of an element of a collection that is a private member of the class. (Essentially ds.get(0).getDeepValue()) The client code doesn't know how deep the rabbit hole goes, only that A exposes a method which returns a Mumble. Client doesn't even need to know that the classes B, C, D, E, or List exist anywhere!
Additionally, if I were designing this system from the ground up, I would take a good long look at whether it could be restructured such that the actual Mumble object wasn't so deep. If I could reasonably get away with storing the Mumble within A or B, I'd recommend doing it. Depending on the application, that may not be possible however.
in terms of performance solution 3 is the best one. In addition It is neat and easy to understand , For example looking at a loop example:
int[] b = somevalue;
for(int i=0;i<b.length;i++){
//do something
}
in this case for every iteration we execute the condition. However, there is another approach for it which uses try and catch
int[] b = somevalue;
try{
for(int i=0;;i++){
//do something
}
}catch(IndexOutOfBoundException e){
// do something
}
on the second solution,the loop keeps going until we reach the end of the loop which then it throws IndexOutOfBoundException as soon as we reach the end of the array. meaning we don't check for the condition no more. thus faster.

How avoid multiple IF loops in Java [duplicate]

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.)

Categories