jdk14至16——record关键字

文章详细介绍了Java中的Record类型,它用于封装不可变对象,自动产生构造方法、get方法、equals()、hashCode()和toString()。Record是final的,不能被继承,但可以实现接口。文中通过示例展示了Record的定义、使用及自动生成的代码结构,并利用javap进行反编译查看其特性。此外,还包含了一个Record实现接口的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

record类型是从14开始预览到16成为正式版的,record类型是一种受限制的类,一般用来封装不可变对象,record类型会自动生成一个全部属性的构造方法,以及属性的get方法,但没有set方法,会自动生成hashCode()、equals()、toString()方法;(有点像Lombok的@Data功能)

另外自动生成的get方法不会使用getXxxx()的名字,而是直接用xxxx(),没有get这个单词前缀;

record生成的类是final修饰的,并且只有一个java.lang.Record父类,不能继承也不能被继承,但是可以实现接口,record类里也可以有实例方法、静态属性和静态方法,但是不能有实例属性,也可以有自定义的构造方法,构造方法里再用this(xxxx)调用自动生成的构造方法,也可以使用不带括号和参数的构造方法对自动生成的构造方法进行调整;

定义一个record类型很简单,可以在独立文件里定义:

package test;

public record MyRecord(String name, int age) {
	
}

也可以定义成类属性:

public record MyRecord2(int x, int y) {}

也能定义在方法内部:

	public void test() {
		record MyRecord3(String s) {}
	}

用来临时做一些记录很方便;

可以用javap看一下record类型自动生成的类的样子:

先定义一个名叫A.java的record类型:

然后javac A.java编译下,再用javap -p A.class查看属性和方法:

可以看到是一个final类并且继承java.lang.Record类,所有自动生成的方法都是public的,属性是private final的;

另外Class类还新增了用来处理Record类型的方法:

public boolean isRecord():判断class是不是record类型;

public RecordComponent[] getRecordComponents():返回记录组件,可用来反射动态调用;

测试demo:

MyRecord类:

package test;

public record MyRecord(String name, int age) {
	
	private static String info = "这是一个用于记录name和age的record";
	
	public MyRecord {
		name = name.toUpperCase();	//生成的构造方法里将名字变大写
		age = age + 1;	//生成的构造方法里将age都加1
	}
	
	public MyRecord(String firstName, String lastName, int age) {
		this("%s %s".formatted(firstName, lastName), age);
	}
	
	public void say() {
		System.out.println("你好,我是" + name);
	}
	
	public static String getRecrodInfo() {
		return info;
	}
	
}

main测试类:

package test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;

public class MainTest {
	
	public record MyRecord2(int x, int y) {}

	public static void main(String[] args) {
		MyRecord x = new MyRecord("Tom", 12);
		System.out.println(x.name());
		System.out.println(x.age());
		System.out.println(x);
		
		System.out.println("IsRecord=" + MyRecord.class.isRecord());
		
		System.out.println("=".repeat(40));
		RecordComponent[] comp = MyRecord.class.getRecordComponents();
		for (RecordComponent c : comp) {
			System.out.println("RecordComponent:" + c);
			Method method = c.getAccessor();
			try {
				System.out.println("_method:" + method);
				System.out.println("_method result:" + method.invoke(x, null));
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println("=".repeat(40));
		MyRecord x2 = new MyRecord("John", "Smith", 23);	
		System.out.println(x2);
		x2.say();
		System.out.println(MyRecord.getRecrodInfo());
	}
	
	public void test() {
		record MyRecord3(String s) {}
	}

}

运行结果:

实现接口的小例子:

package test;

public class MainTest {
	
	interface MyInterface {
		void fun();
	}
	
	record MyRecord(String s) implements MyInterface {
		@Override
		public void fun() {
			System.out.println("s=" + s);
		}
	}
	
	public static void main(String[] args) {
		MyRecord r = new MyRecord("HELLO WORLD");
		System.out.println(r);
		r.fun();
	}
	
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值