[英]Default implementation for hashCode() and equals() for record vs class in Java
嘗試使用示例代碼來檢查record與class的equals()
和hashCode()
的默認行為,但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
任何人都可以幫助我理解記錄s default implementation for
等於and
hashCode` 的行為與上述不同嗎?
如果equals
和hashCode
實現有變化以備記錄,那么請幫助我了解該變化的確切目的以及在哪些情況下使用它會更有幫助。
簡而言之,區別很簡單:
java.lang.Object
的equals()
和hashCode()
的默認實現永遠不會認為兩個對象equal
,除非它們是同一個對象(即它是“對象標識”,即x == y
)。equals()
和hashCode()
的默認實現將考慮所有組件(或字段)並比較它們是否相等(或考慮它們的哈希碼)。 如果它們都匹配,則.equals()
將返回true
並且hashCode
將返回相同的值。在合理可行的情況下,由 Object 類定義的 hashCode 方法確實為不同的對象返回不同的整數。 (在某個時間點,hashCode 可能會或可能不會被實現為對象內存地址的某個函數。)
實際上,這意味着任何在其類型層次結構中的任何地方都沒有覆蓋hashCode
的對象將返回所謂的“身份哈希碼”,它實際上是一個任意但恆定的數字。
當且僅當參數是與此記錄相同的記錄類的實例,並且此記錄的每個組件都等於參數的相應組件時,隱式提供的實現才返回 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.