11

Consider the following Java code:

    Object a = new Integer(2);
    Object b = new Integer(2);
    System.out.println(a.equals(b));

    Object x = new Object();
    Object y = new Object();
    System.out.println(x.equals(y));

The first print statement prints true and the second false.

If this is an intentional behavior, how this helps programming in Java?

If this is not an intentional behavior, is this a defect in Java?

siva636
  • 16,109
  • 23
  • 97
  • 135

5 Answers5

31

I'm going to answer your question with reservations, but you should know that you are hurting yourself if the intent of the question was to get you to learn and your solution was to ask StackOverflow. That aside...

This behavior is intentional.

The default equals() method on java.lang.Object compares memory addresses, which means that all objects are different from each other (only two references to the same object will return true).

java.lang.Integer overrides this to compare the value of the Integers, so two different Integers both representing the number two compare equal. If you used == instead, you would get false for both cases.

Standard practice in Java is to override the equals method to return true for objects which have the same logical value, even if they were created at different times (or even with different parameters). It's not very useful to have objects representing numbers if you don't have a way to ask, "do these two things represent the same value?".

Incidentally, and this is a tangent here, Java actually keeps a cache of Integer objects for small values. So sometimes you may get two Integer objects where even the == operator will return true, despite you getting them from two different sources. You can even get code that behaves differently for larger integers than it does for smaller, without having it look at the integral values!

Michael
  • 41,989
  • 11
  • 82
  • 128
Borealid
  • 95,191
  • 9
  • 106
  • 122
  • While we have the == operator to check the memory address eqality, why Object defines a method to check the memory address and then let subclasses like Integer() overwrite it to be used in a different way?! – siva636 Feb 14 '12 at 14:01
  • @MISS_DUKE Because you can't override `==`. And the subclasses don't really make it be used "in a different way" - there's an expectation that each class will make it do the same *logical* thing for that particular class. This is a principle of inheritance: if you have a `makeSound()` method, for a Duck it would be "quack", and for a cow it would be "moo", but overall it makes the right sound for the implementing animal. – Borealid Feb 14 '12 at 14:10
  • That means there are classes that do not override the original equals method, am I right? (please name such a class as an example if I am right) :) – siva636 Feb 14 '12 at 14:18
  • 1
    @MISS_DUKE Yes, there are classes that don't override `equals()`. That would actually be *most* classes - if you choose a class at random, odds are good it didn't (like `java.awt.Canvas` - what would define two different canvases as being "the same"?). – Borealid Feb 14 '12 at 14:24
  • Great, I got it now. Thank you Borealid. – siva636 Feb 14 '12 at 14:35
7

This is intended behaviour.

Object.equals() considers the object identity (i.e. an object is only equal to itself), which is the only thing you can do for generic objects.

Integer overrides the method to depend on the integer value, since two Integer objects with the same value are logically equal. Many other classes also override equals() since it's a core mechanism of the standard API and a lot of functionaliy e.g. in the collections framework depends on it.

Why do are you puzzled by the behaviour anyway? Most people are only confused by the == operator not behaving like that (it works like Object.equals()).

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
3

The equals method in Java serves a specific purpose: it determines if the objects are logically equal, i.e. their content is the same, whatever that may mean in the context of each specific class. This is in contrast to the objects being the same: two different objects could be logically equivalent.

Going back to your example, a and b are different objects that represent the same logical entity - an integer value of 2. They model the same concept - an integer number, and integer numbers with the same value are identical to each other. a and b are, therefore, equal.

The x and y objects, on the other hand, do not represent the same logical entity (in fact, they do not represent anything). That's why they are neither the same nor are equivalent.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

It is intentional, of course.

When comparing Integer objects, equals returns true if their values (in your case, 1) are equal.

Applied on different objects of type Object, it returns false.

x.equals(x)

would return true.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
0

See also Object.equals() doc. By the way, consider using Integer.valueOf(2) rather than new Integer(2) as it reduces memory footprint.

One last funny thing Integer.valueOf(2)==Integer.valueOf(2) will return true but Integer.valueOf(2000)==Integer.valueOf(2000) will return false because in the first case you will receive twice the same instance of the Integer object (there is a cache behind) but not in the second case because the cache is only for values between -127 to 128

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Your answer is not really related to the question. The result of == is normal not funny. The operator == compare the reference that do not have anything to do with the value. That why we should use equals or compareTo methods when working with Numbers. – Damian Leszczyński - Vash Feb 14 '12 at 13:50
  • 1
    Well, this is debatable. But obviously he did not know exactly the purpose of the equals method. It is usually confused with the '==' and since we were talking about Integers, I thought that it could be relevant to know that there are some strange behaviours and that sometimes == will output the same result as equals and sometimes not. – Guillaume Polet Feb 14 '12 at 13:58