cle*_*tus 12
如果要一次设置多个变量,只需定义一个函数:
public class Person {
public Person(String firstName, String lastName, Date dateOfBirth) {
set(firstName, lastName, dateOfBirth);
}
public void set(String firstName, String lastName, String dateOfBirth) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
根据定义,对象只构造一次,因此构造函数只被调用一次.
值得注意的一点是:支持不变性更为常见,因此:
public class Person {
private final String firstName;
private final String lastName;
private final Date dateOfBirth;
public Person(String firstName, String lastName, Date dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth == null ? null new Date(dateOfBirth.getTime());
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public Date getDateOfBirth() { return dateOfBirth == null ? null : new Date(dateOfBirth.getTime()); }
public Person withFirstName(String firstName) {
return new Person(firstName, lastName, dateOfBirth);
}
public Person withLastName(String lastName) {
return new Person(firstName, lastName, dateOfBirth);
}
public Person withDateOfBirth(Date dateOfBirth) {
return new Person(firstName, lastName, dateOfBirth);
}
}
Run Code Online (Sandbox Code Playgroud)
因为当你这样做时,许多并发问题就会消失.不仅仅是并发问题.String,BigDecimal,BigInteger和一些其它标准类是不可变的(不可变的装置实例化一次其状态永远不能改变).Date不是.你在上面的代码中看到我必须不断地防御性地复制出生日期?那是因为Date不是一成不变的.如果你没有调用者可以这样做:
public class Person {
private final Date dateOfBirth;
...
public Date getDateOfBirth() { return dateOfBirth; }
}
Person person = new Person(...);
Date date1 = person.getDateOfBirth();
date1.setTime(1000000000L);
System.out.println(person.getDateOfBirth());
Run Code Online (Sandbox Code Playgroud)
出生日期将发生变化.这个问题完全是由Date可变引起的.这是支持不变性的另一个原因.
您的错误是假设您应该编写默认构造函数并使用setter设置所有值.一个对象在创建时应该100%准备就绪,所以你应该编写一个构造函数来初始化它的整个状态.
这不是Java的"神",这是错误的,是你.