记录的 hashCode() 和 equals() 的默认实现与 Java 中的 class
Default implementation for hashCode() and equals() for record vs class in Java
尝试使用示例代码来检查 equals()
和 hashCode()
对于 record 与 class[= 的默认行为36=],但 record 与 class.
的行为似乎有所不同
这是 record 和 class
的代码示例
public class EqualsAndHashcode {
public static void main(String[] args) {
var employeeA = new Employee(101);
var employeeB = new Employee(101);
var employeeAClass = new EmployeeClass(102);
var employeeBClass = new EmployeeClass(102);
var printStream = System.out;
printStream.println("record equals: " + employeeA.equals(employeeB) + "\nhashcode objA: " + employeeA.hashCode() + "\nhashcode objB: " + employeeB.hashCode());
printStream.println("\nclass equals: " + employeeAClass.equals(employeeBClass) + "\nhashcode objA: " + employeeAClass.hashCode() + "\nhashcode objB: " + employeeBClass.hashCode());
}
}
record Employee(int empId) {
}
class EmployeeClass {
int empId;
EmployeeClass(int empId) {
this.empId = empId;
}
}
以上代码执行后输出为:
record equals: true
hashcode objA: 101
hashcode objB: 101
class equals: false
hashcode objA: 935044096
hashcode objB: 396180261
任何人都可以帮助我理解 records default implementation for
equalsand
hashCode` 的行为与上述不同吗?
并且如果 equals
和 hashCode
实现中有更改记录,那么请帮助我了解该更改的确切目的是什么以及在哪些情况下会更有帮助使用。
简而言之,区别很简单:
equals()
和 hashCode()
对于 java.lang.Object
的默认实现永远不会将两个对象视为 equal
除非它们是同一个对象(即它是“对象标识” , 即 x == y
).
- 记录的
equals()
和 hashCode()
的默认实现将考虑所有组件(或字段)并比较它们是否相等(或考虑它们的哈希码)。如果它们都匹配,那么 .equals()
将 return true
和 hashCode
将 return 相同的值。
记录的详细信息 details for java.lang.Object
是:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (The hashCode may or may not be implemented as some function of an object's memory address at some point in time.)
在实践中,这意味着任何不覆盖 hashCode
其类型层次结构中任何地方的对象都将 return 所谓的“身份哈希码”,它实际上是一个任意但恒定的数字.
The implicitly provided implementation returns true if and only if the argument is an instance of the same record class as this record, and each component of this record is equal to the corresponding component of the argument; otherwise, false is returned. Equality of a component c is determined as follows:
- If the component is of a reference type, the component is considered equal if and only if Objects.equals(this.c, r.c) would return true.
- If the component is of a primitive type, using the corresponding primitive wrapper class PW (the corresponding wrapper class for int is java.lang.Integer, and so on), the component is considered equal if and only if PW.compare(this.c, r.c) would return 0.
Apart from the semantics described above, the precise algorithm used in the implicitly provided implementation is unspecified and is subject to change. The implementation may or may not use calls to the particular methods listed, and may or may not perform comparisons in the order of component declaration.
(这些是针对各自的 hashCode
方法,equals
方法具有相似的语言)。
有关更多讨论,请参阅 JEP 395: Records。
尝试使用示例代码来检查 equals()
和 hashCode()
对于 record 与 class[= 的默认行为36=],但 record 与 class.
这是 record 和 class
的代码示例public class EqualsAndHashcode {
public static void main(String[] args) {
var employeeA = new Employee(101);
var employeeB = new Employee(101);
var employeeAClass = new EmployeeClass(102);
var employeeBClass = new EmployeeClass(102);
var printStream = System.out;
printStream.println("record equals: " + employeeA.equals(employeeB) + "\nhashcode objA: " + employeeA.hashCode() + "\nhashcode objB: " + employeeB.hashCode());
printStream.println("\nclass equals: " + employeeAClass.equals(employeeBClass) + "\nhashcode objA: " + employeeAClass.hashCode() + "\nhashcode objB: " + employeeBClass.hashCode());
}
}
record Employee(int empId) {
}
class EmployeeClass {
int empId;
EmployeeClass(int empId) {
this.empId = empId;
}
}
以上代码执行后输出为:
record equals: true
hashcode objA: 101
hashcode objB: 101
class equals: false
hashcode objA: 935044096
hashcode objB: 396180261
任何人都可以帮助我理解 records default implementation for
equalsand
hashCode` 的行为与上述不同吗?
并且如果 equals
和 hashCode
实现中有更改记录,那么请帮助我了解该更改的确切目的是什么以及在哪些情况下会更有帮助使用。
简而言之,区别很简单:
equals()
和hashCode()
对于java.lang.Object
的默认实现永远不会将两个对象视为equal
除非它们是同一个对象(即它是“对象标识” , 即x == y
).- 记录的
equals()
和hashCode()
的默认实现将考虑所有组件(或字段)并比较它们是否相等(或考虑它们的哈希码)。如果它们都匹配,那么.equals()
将 returntrue
和hashCode
将 return 相同的值。
记录的详细信息 details for java.lang.Object
是:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (The hashCode may or may not be implemented as some function of an object's memory address at some point in time.)
在实践中,这意味着任何不覆盖 hashCode
其类型层次结构中任何地方的对象都将 return 所谓的“身份哈希码”,它实际上是一个任意但恒定的数字.
The implicitly provided implementation returns true if and only if the argument is an instance of the same record class as this record, and each component of this record is equal to the corresponding component of the argument; otherwise, false is returned. Equality of a component c is determined as follows:
- If the component is of a reference type, the component is considered equal if and only if Objects.equals(this.c, r.c) would return true.
- If the component is of a primitive type, using the corresponding primitive wrapper class PW (the corresponding wrapper class for int is java.lang.Integer, and so on), the component is considered equal if and only if PW.compare(this.c, r.c) would return 0.
Apart from the semantics described above, the precise algorithm used in the implicitly provided implementation is unspecified and is subject to change. The implementation may or may not use calls to the particular methods listed, and may or may not perform comparisons in the order of component declaration.
(这些是针对各自的 hashCode
方法,equals
方法具有相似的语言)。
有关更多讨论,请参阅 JEP 395: Records。