Java中的“==”和“equals()”有什么区别?

768

我想澄清一下,如果我理解正确的话:

  • == 是引用比较,即两个对象指向同一内存位置
  • .equals() 则比较对象中的值

62
差不多,没错。 - John Kane
13
可以,.equals() 可以被理解为“有实际意义的等价”。 - vikingsteve
可能是如何在Java中比较字符串?的重复问题。 - TylerH
32
“both objects point to the same memory location”这样的语句表达不够精确,会导致理解困难。您的意思是:“两个变量引用同一个对象”。请注意,变量不是对象;变量是指向对象的引用。 对象不会“指向”任何东西。 - Jesper
1
在C#(以及许多其他语言)中,相等运算符(**==)对应于Object.Equals()方法。派生类,如String,可以通过重写.Equals方法来定义两个字符串是==的含义。Java无法这样做。Java String类(以及Java中的任何类)都没有覆盖==**以使其行为符合预期的方法。这意味着你必须自己手动调用.equals() - Ian Boyd
"==" 用于原始类型,而 ".equals()" 用于比较引用类型(如果在引用类型上使用 "==",则默认比较哈希码)。 - Rishon_JR
26个回答

1
字符串池(又称内部化)和整数池 进一步模糊了差异,并且在某些情况下可能允许您对对象使用==而不是.equals。这可能会提高性能,但代价是更复杂的代码。

E.g.:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

复杂性权衡:以下内容可能会让您感到惊讶:
assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

我建议你远离这种微观优化,始终使用.equals来比较对象,使用==来比较基本类型:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);

1
简而言之,答案是“是”。
在Java中,==运算符比较两个对象是否指向相同的内存位置;而.equals()方法实际上比较两个对象是否具有相同的对象值。

1
这是“身份”和“等价”的区别。 a == b 表示 a 和 b 是“相同的”,也就是说,它们是指向内存中完全相同的对象的符号。 a.equals( b ) 表示它们是“等价的”,也就是说,它们是指向在某种意义上具有相同值的对象的符号 - 尽管这些对象可能占据内存中不同的位置。
请注意,在等价性中,如何评估和比较对象的问题会出现 - 即使某些内容不同,复杂对象也可以被视为实际目的相等。对于身份,没有这样的问题。

0

基本上,==比较的是两个对象在堆上是否具有相同的引用,因此除非两个引用链接到同一对象,否则此比较将为false。

equals()是从Object类继承的方法。默认情况下,此方法比较两个对象是否具有相同的引用。这意味着:

object1.equals(object2) <=> object1 == object2

但是,如果您想在同一类的两个对象之间建立相等关系,则应覆盖此方法。如果您已经覆盖了equals()方法,则还非常重要覆盖hashCode()方法。

实现hashCode()方法是Java对象契约的一部分,用于建立相等关系。如果您正在使用集合,并且没有实现hashCode()方法,则可能会发生奇怪的错误。

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

如果你没有实现hashCode(),在执行上述代码后将会打印出null

0

equals()方法主要比较对象的原始内容。

如果我们写

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");

    System.out.println(s1.equals(s2));
    System.out.println(s2.equals(s3));
    System.out.println(s3.equals(s4));

输出结果将会是:

true 
true 
true

因为equals()方法比较对象的内容。 在第一个System.out.println()中,s1和s2的内容相同,因此它打印true。 对于其他两个System.out.println(),结果也是相同的。 再次强调,
    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");
    
    System.out.println(s1 == s2);
    System.out.println(s2 == s3);
    System.out.println(s3 == s4);

输出结果将会是:

true
false 
false

因为 == 运算符主要比较对象的引用而不是值。 在第一个 System.out.println() 中,s1 和 s2 的引用相同,这就是为什么它返回 true。

在第二个 System.out.println() 中,创建了 s3 对象,因此将创建 s3 的另一个引用,并且 s2 和 s3 的引用将不同,因此它返回 "false"。

第三个 System.out.println() 遵循第二个 System.out.println() 的规则,因此它将返回 "false"。


0
简单来说,== 检查两个对象是否指向同一内存位置,而 .equals() 则比较对象中的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接