英文:
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 <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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论