using method that take variable number of parameters - java

I am trying to make a method that build new object of the class (PhoneBook) using different constructors according to the number of parameters ,, but it gives an error
( Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 )
public static PhoneBook createObjects(String fName,String lName,String num,String...optional)
{
n++;
if (optional[0]==null)
ArrayOfObjects[n]=new PhoneBook(fName,lName,num);
else if (optional[1]==null)
ArrayOfObjects[n]=new PhoneBook(fName,lName,num,optional[0]);
return ArrayOfObjects[n];
}

Instead of checking whether optional[0] == null, you should examine optional.length to determine if the optional parameter is present.
The same goes for optional[1].

Rather than checking optional[0] and optional[1] here, you should check to optional.length. Also, keep in mind that optional itself may well be null, so something like:
if(optional != null) {
if(optional.length > 0) {
// I now know that optional has at least one element in it, and optional[0] should be valid, though I don't know that it is non-null.
if(optional.length > 1) {
// I now know that optional[1] is valid, though I do not know it is non-null.
}
}
}
if you NEED non-null:
if(optional.length > 0 && optional[0] != null)
The second part, optional[0] != null will only be called if the first evaluates to true.

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)

Why null check is necessary in the below code?

public boolean isValidCardDetails(CardDetailsTypeBean cardDetailsTypeBean) throws EnrollmentReqInvalidException {
if (cardDetailsTypeBean.getCardNumber() == null || "".equals(cardDetailsTypeBean.getCardNumber())) {
throw new EnrollmentReqInvalidException("ECDOO16", "card no is mandatory");
}
if (cardDetailsTypeBean.getNameOnCard() == null || "".equals(cardDetailsTypeBean.getNameOnCard())) {
throw new EnrollmentReqInvalidException("ECDOO17", "name on card is mandatory");
}
if (cardDetailsTypeBean.getCvv() == 0 || "".equals(String.valueOf(cardDetailsTypeBean.getCvv()))) {
throw new EnrollmentReqInvalidException("ECDOO18", "cvv is mandatory");
}
if (cardDetailsTypeBean.getExpDate() == null || "".equals(cardDetailsTypeBean.getExpDate())) {
throw new EnrollmentReqInvalidException("ECDOO19", "exp date must be required");
}
return false;
}
Well here i want to ask after getting card number and checking null,why we use "".equals there..?? can anyone explain me this? little confused?
This line of code:
cardDetailsTypeBean.getCardNumber() == null || "".equals(cardDetailsTypeBean.getCardNumber())
simply verifies if cardNumber is null or if is equal to the empty string. Empty string is different from null value, so this code checks if every field read by a getter returns a non-empty, non-null value.
It's superfluous, actually.
The reason for this is that the order of the equals statement on the other side of the logical comparison is guaranteed not to produce a NullPointerException, since String.equals(null) is engineered to produce false.
The reason it likely exists the way it does is that it's being made explicit that the code is checking for null and an empty string.
"" isn't the same as null because "" is a String value. Your card number might instantiated with ""
null means the reference of card number has no value.

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)

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

Variable can only be null shows eclipse

I have wriiten a method like this
public ArrayList<T> GetDoctorDetail(String name)
{
if (name!=null || !name.isEmpty() || name!="")
{
//Statements
}
}
but in eclipse !name by underline with a yellow line show
Null pointer access: The variable name can only be null at this location.
why? and what is the solution.
If name is non-null, the conditional || operator won't evaluate the second operand at all. So the only case in which the second operand can be evaluated is when name is null, in which case it will throw.
I suspect you want
if (name != null && !name.isEmpty())
{
// Use name
}
Or possibly:
if (name == null || name.isEmpty())
{
// Show an error message
}
Note that comparing strings with == and != is also almost always the wrong thing to do, as it compares references. You would normally use equals instead. Not only that, but it would be useless anyway here - it could only be equal to "" if it's empty, so it's the exact same condition as the second operand.
The first part of the oR condition will only fail if name = null. Hence the second part will throw a null pointer exception.
The correct way to write that condition is
if (name!=null && (!name.isEmpty() || name!=""))
if (name != null && !name.isEmpty()) {
// Now the name variable has valid content
}
Note - The logic is always much easier to understand if you create "positive" checks:
if (name == null || name.isEmpty()) {
// Now name is either null or empty
} else {
// Now the name has valid content
}
Try to avoid conditions that check for "negative" states, like "is not null" and "is not empty". They're nothing but brain twisters ;)

Categories