Java中==和.equals之间的区别。

我知道这已被覆盖,但我在SO上看到了不一致的论点。

如果我有:

String a = "apple2e"; String b = "apple2e"; System.out.println("a==b? " + a == b); 

搞错了

据我了解,这是因为ab是对同一个对象的两个不同引用( 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)。

由于字符串实习,并且只是因为字符串实习而ab是对同一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打印它的function。 第一个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"; 

这里, ab是存储在两个不同位置的值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。 否则,你可以看到,是通过字符比较做一个字符。