Java中record定义的类和class定义类的区别
一、简介
在Java中,record
和 class
都可以用来定义类,但它们之间存在一些重要的区别。record
是从Java 14开始引入的一种新的类型声明方式,它简化了不可变数据载体类的定义。而class
是Java中定义类的传统方式,具有更高的灵活性。
二、主要区别
1. 不可变性
- record:默认情况下,
record
定义的类是不可变的。这意味着一旦创建了对象,它的状态就不能被修改。 - class:需要手动实现不可变性,例如通过使用
final
修饰符来防止字段被修改。
// record示例
public record Person(String name, int age) {}
// class示例
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2. 简洁性
- record:语法更加简洁,省去了构造函数、getter方法等样板代码。
- class:需要编写更多的代码来定义构造函数、getter/setter方法等。
3. equals() 和 hashCode() 方法
- record:自动实现了
equals()
和hashCode()
方法,基于组件(即属性)进行比较。 - class:如果需要自定义
equals()
和hashCode()
方法,则必须手动实现。
// record示例
Person person1 = new Person("Alice", 25);
Person person2 = new Person("Alice", 25);
System.out.println(person1.equals(person2)); // true
// class示例
Person person3 = new Person("Alice", 25);
Person person4 = new Person("Alice", 25);
System.out.println(person3.equals(person4)); // false,除非手动重写equals()方法
4. toString() 方法
- record:自动生成
toString()
方法,返回包含所有组件值的字符串表示形式。 - class:如果没有重写
toString()
方法,默认会输出类名和哈希码。
// record示例
Person person5 = new Person("Bob", 30);
System.out.println(person5.toString()); // Person[name=Bob, age=30]
// class示例
Person person6 = new Person("Bob", 30);
System.out.println(person6.toString()); // com.example.Person@hashcode
5. 继承
- record:不能继承其他类,但可以实现接口。
- class:可以继承其他类,并且可以实现多个接口。
// record示例
public record Student(String name, int age, String school) implements Comparable<Student> {
@Override
public int compareTo(Student o) {
return Integer.compare(this.age, o.age);
}
}
// class示例
public class Teacher extends Staff implements Educator {
// ...
}
三、总结
record
和 class
在Java中有不同的适用场景。如果你正在定义一个简单的、不可变的数据载体类,那么record
是一个很好的选择;而对于更复杂的情况,如需要继承或有更多行为逻辑时,class
则更为合适。