经过 Java 14,15,16 的不断开发优化反馈,终于 Java 16 我们迎来了 Java 值类型的最终版设计,可以正式在生产使用 Java 值类型相关 API 也就是

但是,使用这个值类型 Record 替代原有的所有 Pojo javabean entity model 类,会遇到很多问题。这些问题包括:

  1. 由于值类型没有原来普通 Object 的对象头等信息,所以对于一些 Object 的特性是不兼容的。
  2. 我们目前使用 Java 开发不可能不使用很多三方 jar 包,各种库。这些库中使用的 Pojo 类型并没有使用值类型。不过,不用太担心,只要这些开源库还比较活跃,那么一定早晚会兼容值类型的。
  3. lombok 可能快速帮助我们生成pojo类

Record 的产生背景

Record 要解决的问题最主要的一点就是,让Java适应现代硬件:在 Java 语言发布之初**,**一次内存访问和一次数字计算的消耗时间是差不多的,但是现在,一次内存访问耗时大概是一次数值计算的 200 ~ 1000 倍。从语言设计上来说,也就是间接访问带来的通过指针获取的需要操作的内存,对于整体性能影响很大。

Java 是基于对象的语言,也就是说,Java 是一种基于指针的间接引用的语言。这个基于指针的特性,给每个对象带来了唯一标识性。例如判断两个 Object 的 ==,其实判断的是两个对象的内存相对映射地址是否相同,尽管两个对象的 field 完全一样,他们的内存地址也不同。同时这个特性也给对象带来了多态性,易变性还有锁的特性。但是,并不是所有对象都需要这种特性。

由于指针与间接访问带来了性能瓶颈,Java 准备对于不需要以上提到的特性的对象移除这些特性。于是乎Record 出现了。

快速案例

package Record;

public record User(int id, String name) {
}
package Record;

/**
* @author yeqv
* @program A2
* @Classname R1
* @Date 2022/2/9 21:16
* @Email w16638771062@163.com
*/
public class R1 {
public static void main(String[] args) {
var user = new User(1, "张三");
System.out.println(user.id());
System.out.println(user);

}
}

结果:

认真阅读完这篇文章熟练掌握JAVA关于Record值类型的用法_java

Record 类体

Record 类属性必须在头部声明,在 Record 类体只能声明静态属性

public record User(long id, String name, int age) {
static long anotherId;
}

Record 类体可以声明成员方法和静态方法,和一般类一样。但是不能声明 abstract 或者 native 方法

public record User(long id, String name, int age) {
public void test(){}
public static void test2(){}
}

Record 成员

Record 的所有成员属性,都是 public final 非 static 的,对于每一个属性,都有一个对应的无参数返回类型为属性类型方法名称为属性名称的方法,即这个属性的 accessor。前面说这个方法是 getter 方法其实不太准确,因为方法名称中并没有 get 或者 is 而是只是纯属性名称作为方法名。

这个方法如果我们自己指定了,就不会自动生成:

public record User(long id) {
@Override
public long id() {
return id;
}
}

如果没有自己指定,则会自动生成这样一个方法:

  1. 方法名就是属性名称
  2. 返回类型就是对应的属性类型
  3. 是一个 public 方法,并且没有声明抛出任何异常
  4. 方法体就是返回对应属性
  5. 如果属性上面有任何注解,那么这个注解如果能加到方法上那么也会自动加到这个方法上