Java 14是在几周前问世的,它引入了Record类型,它是一个不变的数据载体类,旨在容纳一组固定的字段。 请注意,这是预览语言功能 ,这意味着必须使用--enable-preview
标志在Java编译器和运行时中显式启用它。
我将直接介绍一个Book
记录示例,该记录旨在保存书名,作者,出版日期和价格。 这是记录类的声明方式:
public record Book(String title, String author, LocalDate publishDate, double price) { }
您可以使用javap
查看编译器自动生成的代码:
public final class Book extends java.lang.Record {
public Book(java.lang.String, java.lang.String, java.time.LocalDate, double );
public java.lang.String title();
public java.lang.String author();
public java.time.LocalDate publishDate();
public double price();
public java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object); }
如上所示,编译器自动生成了构造函数,getter方法, hashCode
, equals
和toString
,从而使我们不必键入很多样板代码。
但是,记录不仅可以节省键入时间。 它们还使您的意图明确了,您希望将不可变数据项建模为一组相关字段。
用于现场验证的紧凑型构造器
现在,假设您要向记录添加验证和默认值。 例如,您可能要验证未以负价或未来发布日期创建Book
记录。 可以使用紧凑的构造函数来完成此操作,如下所示:
public record Book(String title, String author, LocalDate publishDate, double price) {
//compact constructor (no parameter list), used for validation and setting defaults
public Book {
if (price < 0.0 ) {
throw new IllegalArgumentException( "price must be positive" );
}
if (publishDate != null && publishDate.isAfter(LocalDate.now())) {
throw new IllegalArgumentException( "publishDate cannot be in the future" );
}
this .author = author == null ? "Unknown" : author;
} }
紧凑的构造函数没有参数列表。 它验证价格和发布日期,并为作者设置默认值。 在此构造函数中未分配的字段(即title
, publishDate
和price
)在此构造函数的末尾隐式初始化。
替代构造函数和其他方法
记录使您可以定义其他方法,构造函数和静态字段,如下面的代码所示。 但是,请记住,从语义上说,一条记录被设计为数据载体,因此,如果您觉得要添加额外的方法,则可能是需要一个类而不是一条记录。
public record Book(String title, String author, LocalDate publishDate, double price) {
// static field
private static final String UNKNOWN_AUTHOR = "UNKNOWN" ;
// compact constructor, used for validation and setting defaults
public Book {
if (price < 0 ) {
throw new IllegalArgumentException( "price must be positive" );
}
if (publishDate != null && publishDate.isAfter(LocalDate.now())) {
throw new IllegalArgumentException( "publishDate cannot be in the future" );
}
this .author = author == null ? UNKNOWN_AUTHOR : author; ? UNKNOWN_AUTHOR : author;
}
// static factory constructor
public static Book freeBook(String title, String author, LocalDate publishDate) {
return new Book(title, author, publishDate, 0.0 );
}
// alternative constructor, without an author
public Book(String title, LocalDate publishDate, double price) {
this (title, null , publishDate, price);
}
// additional method to get the year of publish
public int publishYear() {
return publishDate.getYear();
}
// override toString to make it more user friendly
@Override
public String toString() {
return String.format( "%s (%tY) by %s for £%.2f" , title, publishDate, author, price);
} }
翻译自: https://www.javacodegeeks.com/2020/04/java-14-records.html