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