# Java16新特性
# Record
Record 是 Java 16 正式引入的特性,它是一种不可变数据载体的简化语法,专门用来替代那些只保存数据、充斥着 getter/equals/hashCode/toString 模板代码的数据类。
在 Java 16 之前,我们要写一个仅用于存储数据的类,需要大量模板代码
// 传统数据类(模板代码冗余)
public class User {
private final String id;
private final String name;
private final int age;
// 构造方法
public User(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// Getter 方法
public String getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
// equals、hashCode、toString
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(id, user.id) && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age);
}
@Override
public String toString() {
return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + '}';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
用 Record 改写上面的 User 类,代码会极度简洁
// Record 数据类(自动生成模板代码)
public record User(String id, String name, int age) {}
1
2
2
此外除了这个功能外,record数据类中还能定义添加静态方法、实例方法、自定义构造器(用于校验)
public record User(String id, String name, int age) {
// 自定义紧凑构造器(用于参数校验)
public User {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
// 自定义实例方法
public String getFullInfo() {
return id + "-" + name + "(" + age + ")";
}
// 静态方法
public static User createGuest() {
return new User("guest", "游客", 0);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Record 本质上是一种特殊的类,它隐式继承自 java.lang.Record,不能再继承其他类,但可以实现接口。
不过我觉得,你都需要创建方法校验了,还不如直接创建个类呢,有时候在开发中用来接收Api的请求和响应参数还是很不错的
# instance of新模式
public class NewInstanceVSOld {
public static void main(String[] args) {
Object obj = "Hello, Pattern Matching";
// 旧写法:判断类型,再强转
if (obj instanceof String) {
String str = (String) obj; // 重复写类型,冗余
System.out.println("字符串长度:" + str.length());
}
// 新写法:判断类型的同时声明变量,直接使用
if (obj instanceof String str) {
System.out.println("字符串长度:" + str.length()); // 无需强转,直接用 str
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16