本篇内容主要讲解“Java 14中Record类型的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java 14中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,请调用其构造函数并在其中传递所有字段信息。然后,我们可以使用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);
}
}
程序输出:
1
howtodoinjava@gmail.com
EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta,
email=howtodoinjava@gmail.com, age=38]
当我们创建 EmployeeRecord
时,编译器会创建字节码,并在生成的类文件中包含以下内容:
接受所有字段的构造函数。
toString()
方法,用于打印Record中所有字段的状态/值。
使用基于 invokedynamic
的机制的 equals()
和 hashCode()
方法。
其名称类似于字段名称的getter方法,即 id()
, firstName()
, lastName()
, email()
和 age()
。
类扩展了java.lang.Record
,它是所有Record的基类。这意味着Record不能扩展其他类。
该类被标记为 final
,这意味着我们无法创建它的子类。
它没有任何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都扩展了 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的组件添加注释,这些注释适用于它们。例如,我们可以将 @Transient
批注应用于 id
字段。
public record EmployeeRecord(
@Transient Long id,
String firstName,
String lastName,
String email,
int age)
{
//
}
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;
}
}
程序输出:
EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta,
email=howtodoinjava@gmail.com, age=38]
添加到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;
}
}
我们可以添加构造器特定代码,以在紧凑的构造器中进行数据验证。
我们不需要为字段指定构造函数参数的分配,因为它以通常的方式在规范构造函数中发生。
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");
}
}
}
到此,相信大家对“Java 14中Record类型的介绍”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/273579540/blog/5050314