以前我们定义类都是用 class
关键词,但从 Java 16 开始,我们将多一个关键词 record
,它也可以用来定义类。record
关键词的引入,主要是为了提供一种更为简洁、紧凑的 final
类的定义方式。
下面就来具体了解 record 类的细节。
声明 record 类
声明 record 类的基础语法:
record range(int start, int end){}
我们知道 class 类可以在单独文件中声明,也可以在其他类中声明。那么 record 类也一样,它有这几种申明方式:
- 单独文件申明:
public record range(int start, int end){}
- 在类内部申明:
public class RecordTest { public record range(int start, int end){} }
- 函数内申明:
public class RecordTest { public void test() { public record range(int start, int end){} } }
record 类详解
在知道了如何申明之后,你一定会想用 record
申明的就那么点元素,它到底会具备什么能力呢?
因为 record
关键词申明类主要是为了简化一些类的申明,所以它本质就是一类特殊的 class,或者说是某一个模版的 class。
record
申明的类,具备这些特点:
- 它是一个
final
类 - 自动实现
equals
、hashCode
、toString
函数 - 成员变量均为
public
属性
所以,对于之前写的 range 类,它等价于一个这样的类:
public final class range{ final int start; final int end; public range(int start, int end) { this.start = start; this.end = end; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; range range = (range) o; return start == range.start && end == range.end; } @Override public int hashCode() { return Objects.hash(start, end); } @Override public String toString() { return "range{" + "start=" + x + ", end=" + y + '}'; } public int start(){ return start; } public int end(){ return end; } }
因为一些函数是隐藏的,在 range 定义的时候,我们看不到,所以我们可以尝试写这样一段测试代码来验证一下:
@Test public void test() { range r = new range(100, 200); log.info(r.toString()); range r2 = new range(100, 200); log.info(String.valueOf(r.equals(r2))); }
定义成员函数
因为 record
申明的本质也是类,那么定义成员函数肯定也是可以的。
比如,我们可以这样在 record
类中定义成员函数:
record range(int start, int end){ int distance(){ return end - start; } }
然后,就可以这样调用它:
range r = new range(100, 200); r.distance();