I personally don't see anything wrong with a class utilizing several constructors however there are pro's and con's to everything.
If you want to maintain only a single constructor and optionally supply what you want then perhaps something like this may help:
public class Person {
private String name;
private int age;
private int level;
private int id;
/**
* This constructor is setup so that it can be supplied with any number of
* field arguments or none at all (rely on Setters). If arguments are supplied
* then they <b>must</b> be supplied is the following order:<pre>
*
* <b>Name, Age, Level, ID</b></pre><br>
*
* You can not supply: <b>Name, Level, ID</b> however if you want to skip a
* parameter then you can supply: <b>Name, null, Level, ID</b>. If a Null or
* a Null String ("") is supplied to a parameter then the value for that field
* the parameter is related to is not changed and the declared default would
* apply to it. The following would be a valid uses of this constructor:<pre>
*
* Person p = new Person();
* Person p = new Person("John Doe", 34, 366, 1001);
* Person p = new Person("John Doe", 34, 366);
* Person p = new Person("John Doe", 34);
* Person p = new Person("John Doe");
* Person p = new Person("John Doe", null, 366, 1001);
* Person p = new Person(null, null, 366, 1001);
* Person p = new Person("", "", 366, 1001);
* Person p = new Person("", "", 366, null);
* Person p = new Person("John Doe", "34", "366", "1001");
* Person p = new Person("John Doe", "34", "", "1001");
*
* as some examples.</pre>
*
* You will of noticed in the constructor examples above that any one the parameters can
* be supplied a string. Where Integers are required there can be string representations
* of integer values...as long as they are valid integer representations. If the a
* any numerical value is supplied to the <b>name</b> parameter then an exception is
* thrown.
*
* @param args (Optional - Object) The optional parameters to be supplied if desired.
* The parameters follow this entry order: <b>Name, Age, Level, ID</b>. Name must be
* a string, Age must be Integer or a string representation of an Integer, Level must
* be Integer or a string representation of an Integer, ID must be Integer or a string
* representation of an Integer. Any parameter can be passed a Null or a Null String ("")
* in which case that corresponding parameter's related field will fall to its default
* value.
*/
public Person(Object... args) {
if (args.length > 0) {
String invalidString = "Person Class Constructor Error - "
+ "Invalid Argument Supplied! (" + java.util.Arrays.toString(args)
.replaceAll("[\\[\\]]", "") + ")";
try {
// Name parameter...
if (args.length >= 1 && args[0] != null && !args[0].toString().equals("")) {
if (args[0].toString().matches("\\D+")) {
this.name = args[0].toString();
}
else {
throw new Exception("Not a proper String for Name field! "
+ "It contains digits!");
}
}
// Age parameter...
if (args.length >= 2 && args[1] != null && !args[1].toString().equals("")) {
if (args[1].toString().matches("\\d{1,3}")) {
if (args[1] instanceof String && !args[1].toString().equals("")) {
args[1] = Integer.valueOf(args[1].toString());
}
if (!args[1].toString().equals("")) {
this.age = (int) args[1];
}
}
else {
throw new Exception("Not a proper Integer value for Age field!");
}
}
// Level parameter...
if (args.length >= 3 && args[2] != null && !args[2].toString().equals("")) {
if (args[2].toString().matches("\\d+")) {
if (args[2] instanceof String && !args[2].toString().equals("")) {
args[2] = Integer.valueOf(args[2].toString());
}
if (!args[2].toString().equals("")) {
this.level = (int) args[2];
}
}
else {
throw new Exception("Not a proper Integer value for Level field!");
}
}
// ID parameter...
if (args.length >= 4 && args[3] != null && !args[3].toString().equals("")) {
if (args[3].toString().matches("\\d+")) {
if (args[3] instanceof String && !args[3].toString().equals("")) {
args[3] = Integer.valueOf(args[3].toString());
}
if (!args[3].toString().equals("")) {
this.id = (int) args[3];
}
}
else {
throw new Exception("Not a proper Integer value for ID field!");
}
}
}
catch (Exception ex) {
System.err.println(invalidString);
System.err.println(ex.toString());
// Close Application!
// Do whatever you like on a Constructor Failure.
System.exit(0);
}
}
}
// GETTERS and SETTERS
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// An overriden toString() method
@Override
public String toString() {
return new StringBuilder("").append("Name = ").append(name).append(", Age = ")
.append(age).append(", Level = ").append(level).append(", ID = ")
.append(id).toString();
}
}
Example Constructor Usage:
Person p = new Person("John Doe", 34, 366, 1001);
System.out.println(p.toString());
Read the Constructor's JavaDoc.