繁体   English   中英

Java 中记录与类的 hashCode() 和 equals() 的默认实现

[英]Default implementation for hashCode() and equals() for record vs class in Java

尝试使用示例代码来检查recordclassequals()hashCode()的默认行为,但recordclass相比似乎表现不同。

这是记录的代码示例

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

任何人都可以帮助我理解记录s default implementation for等于and hashCode` 的行为与上述不同吗?

如果equalshashCode实现有变化以备记录,那么请帮助我了解该变化的确切目的以及在哪些情况下使用它会更有帮助。

简而言之,区别很简单:

  • java.lang.Objectequals()hashCode()的默认实现永远不会认为两个对象equal ,除非它们是同一个对象(即它是“对象标识”,即x == y )。
  • 记录的equals()hashCode()的默认实现将考虑所有组件(或字段)并比较它们是否相等(或考虑它们的哈希码)。 如果它们都匹配,则.equals()将返回true并且hashCode将返回相同的值。

java.lang.Object的详细记录详细信息是:

在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (在某个时间点,hashCode 可能会或可能不会被实现为对象内存地址的某个函数。)

实际上,这意味着任何在其类型层次结构中的任何地方都没有覆盖hashCode的对象将返回所谓的“身份哈希码”,它实际上是一个任意但恒定的数字。

对于java.lang.Record它说

当且仅当参数是与此记录相同的记录类的实例,并且此记录的每个组件都等于参数的相应组件时,隐式提供的实现才返回 true; 否则,返回 false。 分量 c 的相等性确定如下:

  • 如果组件是引用类型,则当且仅当 Objects.equals(this.c, rc) 返回 true 时,组件才被视为相等。
  • 如果组件是原始类型,则使用相应的原始包装类 PW(int 的相应包装类是 java.lang.Integer,依此类推),当且仅当 PW.compare(this. c, rc) 将返回 0。

除了上述语义之外,隐式提供的实现中使用的精确算法是未指定的,并且可能会发生变化。 实现可能会或可能不会使用对列出的特定方法的调用,并且可能会或可能不会按组件声明的顺序执行比较。

(这些是针对各自的hashCode方法, equals方法具有相似的语言)。

有关更多讨论,请参阅JEP 395:记录

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM