如何处理具有不同参数的构造函数

huangapple 未分类评论55阅读模式
英文:

How to deal with constructor with different arguments

问题

我创建一个名为Person的类:

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) {
        //...
    }
}
我只能在创建新的Person对象时提供4个参数。但是我希望在没有等级或编号或两者都没有时也能有效。因此,我创建了另外3个构造函数来实现这一点。但是是否有更高效的方法呢?我认为构造函数过多并不好。
英文:
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.

答案1

得分: 1

Sure, here's the translation of the provided content:

使用 lombok 的 @Builder 注解

@Builder
public class Person {
     private String name;
     private int age;
     private int level;
     private int id;
}

创建

Person.builder().age(1).build();
Person.builder().id(1).age(1).build();
英文:

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();

答案2

得分: 1

以下是您提供的代码的翻译部分:

我个人认为类使用多个构造函数没有什么问题但是每种方法都有其利弊

如果您只想维护一个构造函数并且可以根据需要提供参数那么可能可以使用类似以下的方式

public class Person {

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

    /**
     * 此构造函数设置为可以提供任意数量的字段参数或不提供任何参数(依赖于设置器)。如果提供了参数,
     * 则必须按照以下顺序提供参数:<pre>
     * 
     *              <b>Name, Age, Level, ID</b></pre><br>
     * 
     * 不能提供:<b>Name, Level, ID</b>,但是如果要跳过参数,则可以提供:<b>Name, null, Level, ID</b>。
     * 如果向参数传递Null或Null字符串(""),则不会更改该参数相关字段的值,并且将应用声明的默认值。
     * 以下是此构造函数的有效用法示例:<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");
     * 
     * 作为一些示例。</pre>
     * 
     * 你会注意到上面的构造函数示例中,任何一个参数都可以传递一个字符串。在需要整数的地方,可以是整数值的字符串表示形式,
     * 只要它们是有效的整数表示形式。如果将任何数值传递给<b>name</b>参数,则会抛出异常。
     * 
     * @param args(可选 - 对象)要提供的可选参数(如果需要)。参数遵循以下输入顺序:<b>Name、Age、Level、ID</b>。
     * Name必须是字符串,Age必须是整数或整数的字符串表示形式,Level必须是整数或整数的字符串表示形式,
     * ID必须是整数或整数的字符串表示形式。任何参数都可以传递Null或Null字符串(""),
     * 在这种情况下,对应参数的相关字段将恢复为其默认值。
     */
    public Person(Object... args) {
        // 构造函数的实现...
    }

    // 获取器和设置器...
    
    // 重写的toString()方法...
}

**示例构造函数用法**

Person p = new Person("John Doe", 34, 366, 1001);
System.out.println(p.toString());

阅读构造函数的JavaDoc
英文:

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 &lt;b&gt;must&lt;/b&gt; be supplied is the following order:&lt;pre&gt;
     * 
     *              &lt;b&gt;Name, Age, Level, ID&lt;/b&gt;&lt;/pre&gt;&lt;br&gt;
     * 
     * You can not supply: &lt;b&gt;Name, Level, ID&lt;/b&gt; however if you want to skip a 
     * parameter then you can supply: &lt;b&gt;Name, null, Level, ID&lt;/b&gt;. If a Null or 
     * a Null String (&quot;&quot;) 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:&lt;pre&gt;
     * 
     *      Person p = new Person();
     *      Person p = new Person(&quot;John Doe&quot;, 34, 366, 1001);
     *      Person p = new Person(&quot;John Doe&quot;, 34, 366);
     *      Person p = new Person(&quot;John Doe&quot;, 34);
     *      Person p = new Person(&quot;John Doe&quot;);
     *      Person p = new Person(&quot;John Doe&quot;, null, 366, 1001);
     *      Person p = new Person(null, null, 366, 1001);
     *      Person p = new Person(&quot;&quot;, &quot;&quot;, 366, 1001);
     *      Person p = new Person(&quot;&quot;, &quot;&quot;, 366, null);
     *      Person p = new Person(&quot;John Doe&quot;, &quot;34&quot;, &quot;366&quot;, &quot;1001&quot;);
     *      Person p = new Person(&quot;John Doe&quot;, &quot;34&quot;, &quot;&quot;, &quot;1001&quot;);
     * 
     * as some examples.&lt;/pre&gt;
     * 
     * 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 &lt;b&gt;name&lt;/b&gt; parameter then an exception is 
     * thrown.
     * 
     * @param args (Optional - Object) The optional parameters to be supplied if desired. 
     * The parameters follow this entry order: &lt;b&gt;Name, Age, Level, ID&lt;/b&gt;. 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 (&quot;&quot;) 
     * in which case that corresponding parameter&#39;s related field will fall to its default 
     * value.
     */
    public Person(Object... args) {
        if (args.length &gt; 0) {
            String invalidString = &quot;Person Class Constructor Error - &quot;
                        + &quot;Invalid Argument Supplied! (&quot; + java.util.Arrays.toString(args)
                                .replaceAll(&quot;[\\[\\]]&quot;, &quot;&quot;) + &quot;)&quot;;
            try {
                // Name parameter...
                if (args.length &gt;= 1 &amp;&amp; args[0] != null &amp;&amp; !args[0].toString().equals(&quot;&quot;)) {
                    if (args[0].toString().matches(&quot;\\D+&quot;)) {
                        this.name = args[0].toString();
                    }
                    else {
                        throw new Exception(&quot;Not a proper String for Name field! &quot;
                                          + &quot;It contains digits!&quot;);
                    }
                }
                // Age parameter...
                if (args.length &gt;= 2 &amp;&amp; args[1] != null &amp;&amp; !args[1].toString().equals(&quot;&quot;)) {
                    if (args[1].toString().matches(&quot;\\d{1,3}&quot;)) {
                        if (args[1] instanceof String &amp;&amp; !args[1].toString().equals(&quot;&quot;)) {
                            args[1] = Integer.valueOf(args[1].toString());
                        }
                        if (!args[1].toString().equals(&quot;&quot;)) {
                            this.age = (int) args[1];
                        }
                    }
                    else {
                        throw new Exception(&quot;Not a proper Integer value for Age field!&quot;);
                    }
                }
                // Level parameter...
                if (args.length &gt;= 3 &amp;&amp; args[2] != null &amp;&amp; !args[2].toString().equals(&quot;&quot;)) {
                    if (args[2].toString().matches(&quot;\\d+&quot;)) {
                        if (args[2] instanceof String &amp;&amp; !args[2].toString().equals(&quot;&quot;)) {
                            args[2] = Integer.valueOf(args[2].toString());
                        }
                        if (!args[2].toString().equals(&quot;&quot;)) {
                            this.level = (int) args[2];
                        }
                    }
                    else {
                        throw new Exception(&quot;Not a proper Integer value for Level field!&quot;);
                    }
                }
                // ID parameter...
                if (args.length &gt;= 4 &amp;&amp; args[3] != null &amp;&amp; !args[3].toString().equals(&quot;&quot;)) {
                    if (args[3].toString().matches(&quot;\\d+&quot;)) {
                        if (args[3] instanceof String &amp;&amp; !args[3].toString().equals(&quot;&quot;)) {
                            args[3] = Integer.valueOf(args[3].toString());
                        }
                        if (!args[3].toString().equals(&quot;&quot;)) {
                            this.id = (int) args[3];
                        }
                    }
                    else {
                        throw new Exception(&quot;Not a proper Integer value for ID field!&quot;);
                    }
                }
            }
            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(&quot;&quot;).append(&quot;Name = &quot;).append(name).append(&quot;, Age = &quot;)
                .append(age).append(&quot;, Level = &quot;).append(level).append(&quot;, ID = &quot;)
                .append(id).toString();
    }

}

Example Constructor Usage:

Person p = new Person(&quot;John Doe&quot;, 34, 366, 1001);
System.out.println(p.toString());

Read the Constructor's JavaDoc.

huangapple
  • 本文由 发表于 2020年6月29日 10:27:39
  • 转载请务必保留本文链接:https://java.coder-hub.com/62630343.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定