0
public class Person{

     private String name;
     private int age;
     private int level;
     private int id;

     public Person(String name, int age, int level, int id){
        //...
     }
}

I can only have 4 arguments when I create a new Person object. But I want to make it valid when there is no level or id or both. So I created 3 more constructors to do this. But is there any efficient way? I think too many constructors is bad.

SadSalad
  • 69
  • 2
  • 12

2 Answers2

1

use lombok @Builder

@Builder
Public Class Person{
     private String name;
     private int age;
     private int level;
     private int id;
}

create

Person.builder().age(1).build();
Person.builder().id(1).age(1).build();
melody zhou
  • 148
  • 4
1

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.

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22