有效的Java 2e,第43页。
TOPIC:检查参数的字段是否与该对象的相应字段匹配。
某些对象引用字段可能合法地包含null。避免 NullPointerException的可能性,使用这个成语 比较这些字段:
(field == null ? o.field == null : field.equals(o.field))
如果字段和o.field经常是这种替代方案可能会更快 相同:
(field == o.field || (field != null && field.equals(o.field)))
他是否暗示 field.equals(o.field)产生与field == o.field 相同的行为? 有人可以解释第二种选择是如何工作的吗
答案 0 :(得分:3)
(field == o.field ||(field!= null&& field.equals(o.field)))
如果它们都为空,则为真。
如果field
为空,它将安全地短路为假。
如果o.field
为空,则field
对象有责任检查o.field
中的空值,这很好。
如果它们是相同的 - 即它们是相同的对象,而不是根据equals()相等 - 这将返回true并快速完成。
如果它们都不为空且不相等,那么它将评估为false。
他是否暗示field.equals(o.field)产生与field == o.field相同的行为?
当然不是,Java程序员学习的第一件事就是不要将字符串与==进行比较,因为它们不一样。
答案 1 :(得分:2)
(field == o.field || (field != null && field.equals(o.field)))
阅读详细翻译为
If both are null or they are interned then they are `equal`.
If they are not equal and field is not null,
Then the strings may have equality even if they are not interned.
So do a content check for equality of the strings
基本上他所说的是,如果string1 == string2
,那么以太它们都是null
或两者都是not null
,如果两者都不为空并且相等,则字符串必须是interned
。但是,如果string1 != string2
那么其中一件事就是真实的。
这样做的好处是你不必总是按长度比较平等,然后逐个字符地进行比较。如果两个字符串非常非常长,这可能会相当慢。
<强> What is String interning? 强>
代码示例:
public class InternedDemo {
public static void main(String[] args) {
String s1 = "hello world";
String s2 = "hello world";
String s3 = new String("hello world");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s2 == s3); // false
System.out.println(s1.equals(s3)); // true
System.out.println(s2.equals(s3)); // true
}
}