没有
不,Java 不提供任何此类解冻/冻结功能。
建造者
您可以通过“建设者”来满足您的需求。这个想法是你定义一个第二个类来负责产生你的第一个类的实例。这个构建器类为您想要调整的所有各种属性提供了 setter 方法。完成所有设置后,调用.build() 以生成所需类的实例。如果您愿意,所需的实例可能是 immutable。
构建器应从其设置器返回对自身的引用,以提供method-chaining。
如果适合您的问题域,构建器可能会为某些设置设置默认值。
builder 类提供了一些好处:
- 实现您的目标,即生成一个仅在调整其预期值之后才不可变的对象。
- 确保有效值。调用程序员可以使用
isValid 方法验证构建器,然后更正设置。
- 允许在适当的时候返回子类,具体取决于您设置的值。
您可以在与 Java 捆绑的 API 中看到此类构建器。
示例
这是一个构建器的简短示例。
如果需要一个不可变的对象,那么record 可能是合适的。在 Java 16+ 中,记录是定义类的一种简短方式,其主要目的是透明且不可变地传递数据。您只需声明其成员字段的类型和名称。编译器隐式创建默认构造函数、getter、equals & hashCode 和 toString。
public record Employee( UUID id , String name , LocalDate hired ) {}
虽然记录是一种特殊的类,但它仍然是一个类。所以我们可以嵌套另一个类,一个static builder 类。
public record Employee( UUID id , String name , LocalDate hired ) {
public static class Builder { … }
}
这是整个示例类。
package work.basil.building;
import java.time.LocalDate;
import java.util.Objects;
import java.util.UUID;
public record Employee( UUID id , String name , LocalDate hired ) {
public static class Builder {
// ----------- Members
private UUID id;
private String name;
private LocalDate hired;
// ----------- Constructor
public Builder () {
this.id = UUID.randomUUID();
}
// ------- Accessors
public UUID getId () {
return id;
}
public Employee.Builder setId ( UUID id ) {
this.id = Objects.requireNonNull( id );
return this;
}
public String getName () {
return name;
}
public Employee.Builder setName ( String name ) {
Objects.requireNonNull( name );
if ( name.isBlank() ) {
throw new IllegalStateException( "Name must have some text, cannot be blank. Message # 346624fd-cb97-447a-9f56-e09ccf2e97f3." );
} else {
this.name = name;
}
return this;
}
public LocalDate getHired () {
return hired;
}
public Employee.Builder setHired ( LocalDate hired ) {
Objects.requireNonNull( hired );
if ( hired.isAfter( LocalDate.now() ) ) {
throw new IllegalStateException( "Hired date cannot be after today. Message # 181717b8-e2b0-4b5c-9fd2-ee45a2339b09." );
} else {
this.hired = hired;
}
return this;
}
// -------- Logic
public boolean isValid () {
return Objects.nonNull( this.id ) && Objects.nonNull( this.name ) && Objects.nonNull( this.hired );
}
public Employee build () {
if ( this.isValid() ) {
return new Employee( this.id , this.name , this.hired );
} else {
throw new IllegalStateException( "Builder is not valid, so cannot build new object. Message # c0021179-243c-4da5-b265-85208aaaf072" );
}
}
}
}
示例用法。
List <Employee> employees =
List.of(
new Employee.Builder().setName( "Alice" ).setHired( LocalDate.of( 2018 , Month.MARCH, 23) ).build() ,
new Employee.Builder().setName( "Bob" ).setHired( LocalDate.of( 2014 , Month.JANUARY, 28) ).build() ,
new Employee.Builder().setName( "Carol" ).setHired( LocalDate.of( 2013 , Month.JUNE, 17) ).build()
);
运行时。
员工 = [员工[id=9736cb4c-1b32-4924-976b-7340f7f2fdc4,姓名=爱丽丝,受雇=2018-03-23],员工[id=0ac4ff54-51b6-45c9-bb57-59f6efe40cd5,姓名=鲍勃, 雇用=2014-01-28], 雇员[id=52cc9d03-3846-464a-bbed-49f022175bee, 姓名=卡罗尔, 雇用=2013-06-17]]