hashcode() 在编译的时候自动生成字节码实现,核心逻辑基于 ObjectMethods 的 makeHashCode 方法,里面的逻辑是对于每一个属性的哈希值移位组合起来。注意这里的所有调用(包括对于 ObjectMethods 的方法调用以及获取每个属性)都是利用 MethodHandle 实现的近似于直接调用的方式调用的。
equals() 在编译的时候自动生成字节码实现,核心逻辑基于 ObjectMethods 的 makeEquals 方法,里面的逻辑是对于两个 Record 对象每一个属性判断是否相等(对于引用类型用Objects.equals(),原始类型使用 ==),注意这里的所有调用(包括对于 ObjectMethods 的方法调用以及获取每个属性)都是利用 MethodHandle 实现的近似于直接调用的方式调用的。
toString() 在编译的时候自动生成字节码实现,核心逻辑基于 ObjectMethods 的 makeToString 方法,里面的逻辑是对于每一个属性的值组合起来构成字符串。注意这里的所有调用(包括对于 ObjectMethods 的方法调用以及获取每个属性)都是利用 MethodHandle 实现的近似于直接调用的方式调用的。
Record 构造器如果没有指定构造器,Record 类会自动生成一个以所有属性为参数并且给每个属性赋值的构造器。我们可以通过两种方式自己声明构造器:
第一种是明确声明以所有属性为参数并且给每个属性赋值的构造器,这个构造器需要满足:
构造器参数需要包括所有属性(同名同类型),并按照 Record 类头的声明顺序。
不能声明抛出任何异常(不能使用 throws)
不能调用其他构造器(即不能使用 this(xxx))
构造器需要对于每个属性进行赋值。
对于其他构造器,需要明确调用这个包含所有属性的构造器:
public record User(long id, String name, int age) { public User(int age, long id) { this(id, "name", age); } public User(long id, String name, int age) { this.id = id; this.name = name; this.age = age; } }第二种是简略方式声明,例如:
public record User(long id, String name, int age) { public User { System.out.println("initialized"); id = 1000 + id; name = "prefix_" + name; age = 1 + age; //在这之后,对每个属性赋值 } }这种方式相当于省略了参数以及对于每个属性赋值,相当于对这种构造器的开头插入代码。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer: