I have a constructor which accepts an argument, which may be invalid; if it is invalid, I want it to run the constructor's no-argument constructor instead. Otherwise, it should proceed with the given input and do multiple things with that input.
Unfortunately, Java for some reason forces constructor calls to be in the first statement. Is there any way to get around this beyond duplicating code? (my inner programmer dislikes this!)
Ideally, my code in question would work something like this:
public Constructor() {
super();
// some constructor code
}
public Constructor(Object arg) {
if (arg == null) {
this(); // calls the first constructor instead of proceeding
return;
}
super();
/**
* some code to handle the new input,
* if it isn't null
**/
}
However, this obviously isn't possible in Java due to any constructor statements needing to be in the very first statement. Is there an elegant/correct way to deal with this? I was unable to find anything online beyond constructor chaining, which is something else.
Move the code you want to run in the parameterless constructor into the one-parameter constructor:
public YourClass(Object arg) {
super();
if (arg == null) {
// move the code in the parameterless constructor here...
return;
}
/**
* some code to handle the new input,
* if it isn't null
**/
}
Now, the parameterless constructor doesn't need to duplicate that code again - it can just call the one-parameter constructor with null
:
public YourClass() {
this(null);
}
Alternatively, if passing an "invalid" argument to the one-parameter constructor is not an easy thing to do (e.g. if null
is a valid value, and invalid values are identified by inspecting the object itself), you can write everything in a private constructor with a boolean
argument, and do the branching using that.
The idea is basically to have one constructor that every other constructor delegates to, similar to how classes in Kotlin must have a primary constructor.
// you should be able to name the parameters with better names :)
private YourClass(Object arg, boolean parameterlessImplementation) {
if (parameterlessImplementation || !isValid(arg)) {
// move the code in the parameterless constructor here...
} else {
// do things with arg
}
}
public YourClass(Object arg) {
this(arg, false);
}
public YourClass() {
this(null, true);
}