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

cbm*_*eks 3 java comparison reference

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

所以,如果我有:

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + a == b);
Run Code Online (Sandbox Code Playgroud)

搞错了.

据我所知,这是因为a并且b是对同一个对象的两个不同的引用(apple2e).

所以我会有类似的东西:

a (reference_id 123) ------
                           ---------  "apple2e"
b (reference_id 456) ------
Run Code Online (Sandbox Code Playgroud)

现在,如果我只想比较两个字符串的内容,我会用a.equals(b)

这是否意味着如果两个引用指向同一个对象,JVM只是返回?那么它不是真的在进行逐字符比较吗?

谢谢

编辑

拿着电话.谢谢你delnan指出+优先权!

当我将其更改为:

System.out.println(a == b);
Run Code Online (Sandbox Code Playgroud)

我确实得到了true.

这更有意义.

编辑2

我简直不敢相信.大声笑

我在做:

"a==b? " + a == b
Run Code Online (Sandbox Code Playgroud)

这转化为

"a==b? apple2e" == "apple2e"
Run Code Online (Sandbox Code Playgroud)

难怪这是假的!!

Mat*_*all 6

据我了解,这是因为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"
Run Code Online (Sandbox Code Playgroud)

Java会自动插入所有字符串文字.就是为什么第二个sysout打印它的功能.第一个sysout打印只是"false"因为字符串连接(+)的优先级高于==,所以它等效于:

System.out.println("a==b? apple2e" == "apple2e");
Run Code Online (Sandbox Code Playgroud)

我不认为那是你的意思!

另一方面,这将为您提供两个单独的String实例:

String a = new String("apple2e");
String b = new String("apple2e");

System.out.println("a==b? " + (a == b));  // "a==b? false"
Run Code Online (Sandbox Code Playgroud)

这将是示意性的样子

a (reference_id 123) ---------------  "apple2e"

b (reference_id 456) ---------------  "apple2e"
Run Code Online (Sandbox Code Playgroud)

并可以使用以下方法缩小到原始状态String#intern():

String a = new String("apple2e").intern();
String b = new String("apple2e").intern();

System.out.println("a==b? " + (a == b));  // "a==b? true"
Run Code Online (Sandbox Code Playgroud)

例如

a (reference_id 123) ------+
                           +---------  "apple2e"
b (reference_id 456) ------+
Run Code Online (Sandbox Code Playgroud)

  • 不必要.人们通常应该假设,但对于字符串文字,尤其并不总是如此(遗憾的是,这总是引起很多混乱).由于不同的原因,OP正在获得"假"输出.有关两个*相同的示例,请参见http://www.ideone.com/uaTf7. (2认同)
  • 请注意,字符串实习仅起作用,因为Java中的字符串是不可变的.没有什么可以改变这个值,所以你可以简单地让程序的两个完全不同的部分指向同一个字符串,而不用担心一个人改变另一个使用的那个.当然,这并不总是很聪明 - 当您创建一个新的字符串实例以保存一些存储时,您不希望检查每个字符串实例.所以一般来说,当你编译东西时,一切都被实习,但之后你就不知道了.所以总是使用.equals(),特别是因为第一条指令反正是'=='. (2认同)

Aff*_*ffe 6

你的第一个例子实际上是真的.println中的表达式并不符合您的意思.

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + (a == b));
Run Code Online (Sandbox Code Playgroud)

将打印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));
Run Code Online (Sandbox Code Playgroud)

它实际上会打印a==b? false.因为你在内存中创建了两个不同的对象,a和b指向不同的地方.


Pet*_*rey 5

'a'和'b'是相同的参考,问题是你没有比较a和b.你应该期待

a==b? false
Run Code Online (Sandbox Code Playgroud)

但你得到了

false
Run Code Online (Sandbox Code Playgroud)

这是因为+优先于==你所拥有的

System.out.println(("a==b? " + a) == b);
Run Code Online (Sandbox Code Playgroud)

以同样的方式,您希望以下内容打印为true.

System.out.println(1 + 2 == 3);
Run Code Online (Sandbox Code Playgroud)

你需要的是什么

System.out.println("a==b? " + (a == b));
Run Code Online (Sandbox Code Playgroud)