[英]Difference between == and .equals in Java.
我知道这已被覆盖,但我在SO上看到了不一致的论点。
所以,如果我有:
String a = "apple2e";
String b = "apple2e";
System.out.println("a==b? " + a == b);
我搞错了 。
据我了解,这是因为a
和b
是对同一个对象的两个不同引用( apple2e
)。
所以我会有类似的东西:
a (reference_id 123) ------
--------- "apple2e"
b (reference_id 456) ------
现在,如果我只想比较两个字符串的内容 ,我会使用a.equals(b)
这是否意味着如果两个引用指向同一个对象,JVM只是返回? 那么它不是真的在进行逐字符比较吗?
谢谢
编辑
拿着电话。 感谢delnan
指出+
优先!!!
当我将其更改为:
System.out.println(a == b);
我的确是true
。
这更有意义。
编辑2
我简直不敢相信。 大声笑
我在做:
"a==b? " + a == b
这转化为
"a==b? apple2e" == "apple2e"
难怪这是假的!!
据我了解,这是因为a和b是对同一个对象的两个不同引用(apple2e)。
由于字符串实习,并且仅因为字符串内部a
和b
是对同一String
对象的不同引用。
不幸的是,您的代码没有按照您的想法执行。 尝试这个:
String a = "apple2e";
String b = "apple2e";
System.out.println("a==b? " + a == b); // "false"
System.out.println("a==b? " + (a == b)); // "a==b? true"
Java会自动插入所有字符串文字。 这就是为什么第二个sysout打印它的功能。 第一个sysout只打印"false"
因为字符串连接( +
)的优先级高于==
,因此它等效于:
System.out.println("a==b? apple2e" == "apple2e");
我不认为那是你的意思!
另一方面,这将为您提供两个单独的String
实例:
String a = new String("apple2e");
String b = new String("apple2e");
System.out.println("a==b? " + (a == b)); // "a==b? false"
这将是示意性的样子
a (reference_id 123) --------------- "apple2e"
b (reference_id 456) --------------- "apple2e"
并且可以使用String#intern()
简化为原始情况:
String a = new String("apple2e").intern();
String b = new String("apple2e").intern();
System.out.println("a==b? " + (a == b)); // "a==b? true"
例如
a (reference_id 123) ------+
+--------- "apple2e"
b (reference_id 456) ------+
你的第一个例子实际上是真的。 println中的表达式并不符合您的意思。
String a = "apple2e";
String b = "apple2e";
System.out.println("a==b? " + (a == b));
会打印a==b? true
a==b? true
注意到所有重要的分组!
你是对的,a和b是对同一个对象的两个不同的引用。 这正是为什么在测试时==返回true的原因! ==测试两个不同的指针是否指向内存中的相同位置。 a和b都是对内存中相同位置的引用,它保存了interned编译时间“apple2e”字符串。
现在,如果你这样做了
String a = new String("apple2e");
String b = new String("apple2e");
System.out.println("a==b? " + (a == b));
它实际上会打印a==b? false
a==b? false
。 因为你在内存中创建了两个不同的对象,a和b指向不同的地方。
'a'和'b'是相同的参考,问题是你没有比较a和b。 你应该期待
a==b? false
但你得到了
false
这是因为+
优先于==
所以你拥有的是什么
System.out.println(("a==b? " + a) == b);
以同样的方式,您希望以下内容打印为true。
System.out.println(1 + 2 == 3);
你需要的是什么
System.out.println("a==b? " + (a == b));
a == b查看两个对象是否指向内存中的同一对象。 因为他们没有,即使他们的内部是相同的,a == b将是错误的。 1 == 1将是真的,因为整数是原始变量,而字符串实际上是对象。
a.equals(b)是一种实例方法,它在内部检查两个字符串是否具有相同的字符。
如果你这样做:
String a = "hello";
String b = a;
那么 a == b就是真的。
apple2e
不是一个对象。 它是引用指向的值。
String a = "apple2e";
String b = "apple2e";
这里, a
, b
是存储在两个不同位置的值apple2e
对象(引用)。
a和b是对同一对象的两个不同引用 - 可能
"a==b? " + a
计算字符串“a == b?apple2e”,它与字符串“apple2e”绝对不一样(==或等于)
所以你的代码:
System.out.println("a==b? " + a == b);
只是测试“a == b?apple2e”是否与“apple2e”相同而不是(无论你如何定义)。
如果更改为以下内容: System.out.println("a==b? " + (a == b));
你得到a==b? true
a==b? true
这里发生的是a和b都指向由String类维护的字符串的内部缓存。
这是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;
}
anObject
必须是String
才能返回true,如果它是对同一个Object的引用,则它立即返回true。 否则,你可以看到,是通过字符比较做一个字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.