[英]What is a significant field for the equals contract (effective java item 8)
In Effective Java in Item 8 the recommendation is that 在第8项的Effective Java中,建议是这样的
For each significant field in the class to check the corresponding field of the this object.
对于类中的每个重要字段,检查此对象的相应字段。
I understand that we can have secondary fields that are calculated by primary fields but what exactly is the meaning of "for each significant field"? 我知道我们可以有主要字段计算的辅助字段,但“每个重要字段”的含义究竟是什么? Is the
equals
contract implemented properly only when all fields of an object is compared? 仅当比较对象的所有字段时,是否正确实现了
equals
合约?
If I have eg a class Employee
which has a multitude of fields like id, first and last name, dob, position, location etc all these seem significant but to me it seems that just using the id
would suffice for a proper and performant equals
implementation. 如果我有一个类
Employee
,它有很多字段,如id,名字和名字,dob,位置,位置等所有这些看起来很重要,但对我来说,似乎只需使用id
满足正确和equals
实现。
Am I wrong on this? 我错了吗? Or the
id
I mention is exactly what Bloch means by "significant" fields? 或者我提到的
id
正是Bloch在“重要”字段中的含义?
class Employee {
private UUID id;
private String firstName;
private String lastName;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Employee))
return false;
return id.equals(((Employee)obj).id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
In case of Employee
is stored into DB, ie has unique id
, then no need to check other fields like firstName
and lastName
in equals
; 如果
Employee
存储到DB中,即具有unique id
,则不需要检查equals
firstName
和lastName
等其他字段; according to data object comparison, only id
filed is significant . 根据数据对象的比较,只有
id
字段很重要 。
A significant field is merely one that, if omitted, would result in an incorrect implementation of equals (according to the notion of equality you have defined for instances of your class). 一个重要的字段只是一个,如果省略,将导致equals的错误实现(根据您为类的实例定义的相等概念)。
I appreciate that is a bit of a self-referential definition, but that's what it means. 我很欣赏这是一个自我指涉的定义,但这就是它的含义。
The canonical example of a non-significant field is String.hashCode
: as you observe, this is calculated from other fields (and lazily), so it would not be appropriate to include in the equality because there is no guarantee that it has been calculated for either of the strings being compared; 非重要字段的规范示例是
String.hashCode
:正如您所观察到的,这是从其他字段(和懒惰)计算的,因此不适合包含在相等中,因为不能保证它已被计算对于任何一个被比较的字符串; and, if it has been calculated for both, it tells you nothing more than you already know. 并且,如果已经计算了两者,它只会告诉你比你已经知道的更多。
In your case, yes, it sounds like comparing instances using only the id
would suffice: this is a significant field, the name (etc) is not significant: there should only be one person (little p, as in an actual real human) with a particular id. 在你的情况下,是的,这听起来像仅仅使用
id
比较实例就足够了:这是一个重要的字段,名称(等)并不重要:应该只有一个人(小p,如在真正的真实人类中)有一个特定的身份证。
It does raise a question of how you would deal with "same id, different name" instances, but this is getting into the realm of Falsehoods Programmers Believe About Names : 它确实提出了一个问题,即如何处理“相同的id,不同名称”实例,但这进入了Falsehoods程序员相信名称的领域 :
- People have exactly one canonical full name.
人们只有一个规范的全名。
- People have exactly one full name which they go by.
人们只有一个完整的名字。
- People have, at this point in time, exactly one canonical full name.
在这个时间点,人们只有一个规范的全名。
- People have, at this point in time, one full name which they go by.
在这个时间点,人们有一个他们经过的全名。
- People have exactly N names, for any value of N.
对于任何N值,人们都有N个名字。
- (People's names fit within a certain defined amount of space.)
(人们的名字在一定的空间内。)
- People's names do not change.
人们的名字不会改变。
- ...
...
Taking these into consideration, if you want to say "this Person is the same as that Person" (and you want to do that using equals
), id seems like the only reasonable thing to use. 考虑到这些,如果你想说“这个人和那个人一样”(并且你想用
equals
做),id似乎是唯一合理的用法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.