逻辑相等与对象引用相等
Logical Equality versus Object Reference Equality
我正在学习OCA 8 认证。 Java 中的 "Logical Equality" 是什么意思?
我有这个案例:
String s1 = new String("java");
String s3 = new String("java");
StringBuilder s2 = new StringBuilder("java");
StringBuilder s4 = new StringBuilder("java");
if (s1 == s2) { System.out.print("1"); } //error
if (s1.equals(s2)) { System.out.print("2"); } //false
if (s1.equals(s3)) { System.out.print("3"); } //true
if (s2.equals(s4)) { System.out.print("4"); } //false
部分:
对象 String
上的方法 equals()
被重新定义以将对象的值与另一个对象的值进行比较。出于这个原因,当我执行该行时:
if (s1.equals(s3)) { System.out.print("3"); }
我有结果 3.
在对象 StringBuilder
上,方法 equals()
未重新定义,因此它将比较对象引用是否相等。出于这个原因,当我执行代码行时:
if (s2.equals(s4)) { System.out.print("4"); }
我有结果false
。
我的问题是:
- 为什么我执行
if(s1 == s2)
时会出现编译错误?
- 为什么我执行
s1.equals(s2)
的时候是假的?
- Why when i excecute if(s1 == s2) i will be a compile error ?
- Why when i excecute s1.equals(s2) it is false ?
- 是的。因为
String
不是 StringBuilder
。你会得到 "incompatible operand types String and StringBuilder"(因为 String
不是 StringBuilder
)。
- 同样,因为
String
不是 StringBuilder
。您可以使用 s1.equals(s2.toString())
(即 true
)。
- Why when i excecute if(s1 == s2) i will be a compile error ?
==
运算符是 reference equality operator。引用 JLS:
It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5).
在您的例子中,两个操作数的类型为 String
和 StringBuilder
,它们不兼容:String
无法转换为 StringBuilder
和 vice-versa.
- Why when i excecute s1.equals(s2) it is false ?
String
和 StringBuilder
是两种不同的类型。 String
中的 equals()
方法检查给定的参数是否也是 String
类型,这里不是这种情况,因此 String
的实例永远不会等于一个StringBuilder
.
的实例
我刚刚发现原因here。
1012 public boolean equals(Object anObject) {
1013 if (this == anObject) {
1014 return true;
1015 }
1016 if (anObject instanceof String) {
1017 String anotherString = (String)anObject;
1018 int n = count;
1019 if (n == anotherString.count) {
1020 char v1[] = value;
1021 char v2[] = anotherString.value;
1022 int i = offset;
1023 int j = anotherString.offset;
1024 while (n-- != 0) {
1025 if (v1[i++] != v2[j++])
1026 return false;
1027 }
1028 return true;
1029 }
1030 }
1031 return false;
1032 }
我很困惑,因为 equals 方法接受了一个类似对象的参数(为此,我认为它在方法内部被视为一个对象,但我看到它是第二个 if 条件仅适用于 String 对象(在此我找到了关于逻辑相等性问题的答案)。
谢谢大家
我正在学习OCA 8 认证。 Java 中的 "Logical Equality" 是什么意思?
我有这个案例:
String s1 = new String("java");
String s3 = new String("java");
StringBuilder s2 = new StringBuilder("java");
StringBuilder s4 = new StringBuilder("java");
if (s1 == s2) { System.out.print("1"); } //error
if (s1.equals(s2)) { System.out.print("2"); } //false
if (s1.equals(s3)) { System.out.print("3"); } //true
if (s2.equals(s4)) { System.out.print("4"); } //false
部分:
对象 String
上的方法 equals()
被重新定义以将对象的值与另一个对象的值进行比较。出于这个原因,当我执行该行时:
if (s1.equals(s3)) { System.out.print("3"); }
我有结果 3.
在对象 StringBuilder
上,方法 equals()
未重新定义,因此它将比较对象引用是否相等。出于这个原因,当我执行代码行时:
if (s2.equals(s4)) { System.out.print("4"); }
我有结果false
。
我的问题是:
- 为什么我执行
if(s1 == s2)
时会出现编译错误? - 为什么我执行
s1.equals(s2)
的时候是假的?
- Why when i excecute if(s1 == s2) i will be a compile error ?
- Why when i excecute s1.equals(s2) it is false ?
- 是的。因为
String
不是StringBuilder
。你会得到 "incompatible operand types String and StringBuilder"(因为String
不是StringBuilder
)。 - 同样,因为
String
不是StringBuilder
。您可以使用s1.equals(s2.toString())
(即true
)。
- Why when i excecute if(s1 == s2) i will be a compile error ?
==
运算符是 reference equality operator。引用 JLS:
It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5).
在您的例子中,两个操作数的类型为 String
和 StringBuilder
,它们不兼容:String
无法转换为 StringBuilder
和 vice-versa.
- Why when i excecute s1.equals(s2) it is false ?
String
和 StringBuilder
是两种不同的类型。 String
中的 equals()
方法检查给定的参数是否也是 String
类型,这里不是这种情况,因此 String
的实例永远不会等于一个StringBuilder
.
我刚刚发现原因here。
1012 public boolean equals(Object anObject) {
1013 if (this == anObject) {
1014 return true;
1015 }
1016 if (anObject instanceof String) {
1017 String anotherString = (String)anObject;
1018 int n = count;
1019 if (n == anotherString.count) {
1020 char v1[] = value;
1021 char v2[] = anotherString.value;
1022 int i = offset;
1023 int j = anotherString.offset;
1024 while (n-- != 0) {
1025 if (v1[i++] != v2[j++])
1026 return false;
1027 }
1028 return true;
1029 }
1030 }
1031 return false;
1032 }
我很困惑,因为 equals 方法接受了一个类似对象的参数(为此,我认为它在方法内部被视为一个对象,但我看到它是第二个 if 条件仅适用于 String 对象(在此我找到了关于逻辑相等性问题的答案)。 谢谢大家