Java14 - Record类型

Java14 - Record类型 首页 / Java入门教程 / Java14 - Record类型

 Java中Record类型是Java 14中的预览函数引入的,并且应作为普通的 不可变 数据类,用于在类和应用程序之间进行数据传输。

Enum一样,Record也是一个特殊的类输入Java。类(Class)与记录(Record)之间的重要区别是,Record旨在消除设置和从实例获取数据所需的所有代码,Record将这种责任转移给生成编译器。

Record语法

使用关键字record在Java中创建此类Record类。就像在构造函数中所做的一样,需要在Record中提及属性及其类型。

在给定的示例中,EmployeeRecord用于保存员工信息,即

package com.howtodoinjava.core.basic;

public record EmployeeRecord(Long id, 
		String firstName, 
		String lastName, 
		String email, 
		int age) {
	
}

Record使用

要创建一条Record,请调用其构造函数并在其中传递所有字段信息。然后可以使用JVM生成的getter方法获取记录信息,并调用任何生成的方法。

package com.howtodoinjava.core.basic;

public class RecordExample {
	public static void main(String[] args) 
	{
		EmployeeRecord e1 = new EmployeeRecord
				(1l, "Lokesh", "Gupta", "howtodoinjava@gmail.com", 38);
		
		System.out.println(e1.id());
		System.out.println(e1.email());
		
		System.out.println(e1);
	}
}

程序输出:

链接:https://www.learnfk.comhttps://www.learnfk.com/java/java14-java-14-record-type.html

来源:LearnFk无涯教程网

1
howtodoinjava@gmail.com
EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta, 
			email=howtodoinjava@gmail.com, age=38]

Record查看

当无涯教程创建EmployeeRecord时,编译器会创建字节码,并在生成的类文件中包含以下内容:

  1. 接受所有字段的构造函数。
  2. toString()方法,用于打印Record中所有字段的状态/值。
  3. 使用基于invokedynamic的机制的equals()hashCode()方法。
  4. 其名称类似于字段名称的getter方法,即id()firstName()lastName()email()age()
  5. 类扩展了java.lang.Record,它是所有Record的基类。这意味着Record不能扩展其他类。
  6. 该类被标记为final,这意味着无法创建它的子类。
  7. 它没有任何setter方法,这意味着Record实例被设计为不可变的。

如果在生成的类文件上运行javap工具,将看到该类文件。

public final class com.howtodoinjava.core.basic.EmployeeRecord extends java.lang.Record {
  //1							
  public com.howtodoinjava.core.basic
  	.EmployeeRecord(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, int);

  //2
  public java.lang.String toString();

  //3
  public final int hashCode();
  public final boolean equals(java.lang.Object);

  //4
  public java.lang.Long id();
  public java.lang.String firstName();
  public java.lang.String lastName();
  public java.lang.String email();
  public int age();
}

Record不能被继承

尽管所有Record都扩展了java.lang.Record类,但是无涯教程仍然不能显式创建java.lang.Record的子类。编译器不会通过。

final class Data extends Record {
	private final int unit;
}

// Compiler error : The type Data may not subclass Record explicitly

这意味着获取Record的唯一方法是显式声明一个Record并让javac创建类文件。

Record添加注释

无涯教程可以为Record的组件添加注释,这些注释适用于它们。例如,可以将@Transient批注应用于id字段。

public record EmployeeRecord(
		@Transient Long id, 
		String firstName, 
		String lastName, 
		String email, 
		int age) 
{
	//
}

Record序列

Record类的 serialVersionUID 0L,除非它是明确声明。

Record对象序列化的过程无法自定义,Record类定义的任何特定于类的代码 writeObject,readObject,readObjectNoData,readResolve,writeExternal和readExternal方法在序列化和反序列化期间都将被忽略。但是,writeReplace方法可用于返回要序列化的替代对象。

在执行任何 序列化或反序列化之前,无涯教程必须确保Record必须可序列化或可外部化。

import java.io.Serializable;

public record EmployeeRecord (
		Long id, 
		String firstName, 
		String lastName, 
		String email, 
		int age) implements Serializable
{

}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class RecordExample {
	public static void main(String[] args) 
	{
		EmployeeRecord e1 = new EmployeeRecord
				(1l, "Lokesh", "Gupta", "howtodoinjava@gmail.com", 38);
		
		writeToFile(e1, "employee1");
                System.out.println(readFromFile("employee1"));
	}
	
	static void writeToFile(EmployeeRecord obj, String path) {
        try (ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(path))){
            oos.writeObject(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
    static EmployeeRecord readFromFile(String path) {
    	EmployeeRecord result = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))){
            result = (EmployeeRecord) ois.readObject();
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

程序输出:

链接:https://www.learnfk.comhttps://www.learnfk.com/java/java14-java-14-record-type.html

来源:LearnFk无涯教程网

EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta, 
			email=howtodoinjava@gmail.com, age=38]

Record字段和方法

添加到Record中的新字段必须为Static 静态 也可以添加一种方法,该方法可以访问Record字段的内部状态。

编译器不会在隐式生成的字节码中使用添加的字段和方法,因此它们不属于任何方法实现,例如equals()hashCode()toString()

public record EmployeeRecord(
		Long id, 
		String firstName, 
		String lastName, 
		String email, 
		int age) implements Serializable 
{
	//additional field
	static boolean minor;
	
	//additional method
	public String fullName() 
	{
		return firstName + " " + lastName;
	}
}

Record构造函数

可以添加构造器特定代码,以在紧凑的构造器中进行数据验证。

不需要为字段指定构造函数参数的分配,因为它以通常的方式在规范构造函数中发生。

public record EmployeeRecord(
		Long id, 
		String firstName, 
		String lastName, 
		String email, 
		int age) implements Serializable 
{
	public EmployeeRecord
	{
		if(age < 18)
		{
			throw new IllegalArgumentException(
	                "You cannot hire a minor person as employee");
		}
	}
}

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Linux实战技能100讲 -〔尹会生〕

摄影入门课 -〔小麥〕

深度学习推荐系统实战 -〔王喆〕

Spark核心原理与实战 -〔王磊〕

etcd实战课 -〔唐聪〕

程序员的个人财富课 -〔王喆〕

手把手教你落地DDD -〔钟敬〕

结构会议力 -〔李忠秋〕

云时代的JVM原理与实战 -〔康杨〕

好记忆不如烂笔头。留下您的足迹吧 :)