我问的是非常基本的问题,但是真的很困惑equals方法在java中是如何工作的.让我举一个例子,我在类级别声明类型为String的三个变量.
String a = "abc";
String b = "abc";
String c = new String("abc");
Run Code Online (Sandbox Code Playgroud)
然后根据java拇指规则编写一个方法来比较它们.
public void compare(){
System.out.println("a.equals(c) :" + a.equals(c));
System.out.println("a == b :" + (a == b));
System.out.println("a == c :" + (a == c));
}
Run Code Online (Sandbox Code Playgroud)
现在,当我运行程序时,它给了我下面的输出.
a.equals(c) :true
a == b :true
a == c :false
Run Code Online (Sandbox Code Playgroud)
现在我很困惑,因为我知道写成文字的字符串总是被创建到StringPool中.这意味着变量a和b将被创建为StringPool,并且根据stringPool,将只有一个实例,变量a和b将指向此变量.变量c将被创建到堆内存中.当我比较a.equals(c)时,它给了我真实的可能性,因为equals的默认实现总是比较内存分配而不是内容.它应该返回false.
我对整数也做了同样的事情
Integer m = 1;
Integer n = 1;
Integer o = new Integer(1);
public void compareInt(){
System.out.println("m.equals(o) :" + m.equals(o));
System.out.println("m == n :" + (m == n));
System.out.println("m == o :" + (m == o));
}
Run Code Online (Sandbox Code Playgroud)
出去了
m.equals(o) :true
m == n :true
m == o :false
Run Code Online (Sandbox Code Playgroud)
现在再次困惑.所有三个变量都将被创建到头部内存中,因为对于整数,现在有IntegerPool.然后m == n如何给出真实,因为再次==运算符比较引用而不是内容,并且根据我的理解参考是不同的.在这种情况下,equals方法的行为与String中的相同.
有人可以帮助了解发生了什么.
String和Integer重写该equals方法,因此它们不依赖于默认实现.
例如,这是String :: equals的实现:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
哦,整数确实有-128到127之间的值的缓存,这解释了为什么m==n返回true.
| 归档时间: |
|
| 查看次数: |
137 次 |
| 最近记录: |