Reputation: 12023
I've the following test program. I create 3 Integer
references. I create 2 Integer
objects and make references i1 and i2 refer them respectively. I make reference i3 equal to i1. Now i1 equals() i3 should be obviously true as they both refer to same object on heap. But why should i1 be equal() to i2 ? They are refering to two different objects. What am I missing.
The documentation says:
public boolean equals(Object obj) Indicates whether some other object is "equal to" this one.
public class Test{
public static void main(String [] args)
{
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
Integer i3 = i1;
if(i1.equals(i3)) // UNDERSTANDABLE
System.out.println("equal");
if(i1.equals(i2)) // prints equal. WHY !!!!!
System.out.println("equal");
}
}
Upvotes: 1
Views: 4816
Reputation: 41097
They have same value, that's why it is true. Generally equals method does not test if the references are equal although that is the default behavior.
Upvotes: 1
Reputation: 205785
Also note that "Using new Integer(int)
is guaranteed to always result in a new object, whereas Integer.valueOf(int)
allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster." --FindBugs
Compare these statements:
System.out.println("new == " + (new Integer(1) == new Integer(1)));
System.out.println("new equals() " + new Integer(1).equals(new Integer(1)));
System.out.println("valueOf() == "
+ (Integer.valueOf(1) == Integer.valueOf(1)));
System.out.println("valueOf() equals() "
+ Integer.valueOf(1).equals(Integer.valueOf(1)));
which produce this output:
new == false new equals() true valueOf() == true valueOf() equals() true
Upvotes: 1
Reputation: 45714
The equals()
methods for the wrapper types test for value equality, if you want to test reference equality, use ==
instead, e.g.
System.out.println(new Integer(1) == new Integer(1));
Upvotes: 13
Reputation: 6844
The answer to your question has been already said but I have one note. Be careful because your own objects are extended from Object and there is method equal()
implemented like operator ==
so if you want to compare values you have to override it.
Upvotes: 1
Reputation: 22477
If you read further in the JavaDoc, it provides more details, specifically:
Indicates whether some other object is "equal to" this one. The equals method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value x, x.equals(x) should return true.
- It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
- It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
- It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
- For any non-null reference value x, x.equals(null) should return false.
Specifically, it is up to the implementor of "equals(Object)" to decide if two objects are "equal." For reference comparison, us the ==
operator as others have pointed out.
I also encourage you to read Effective Java if you're interested in this (and other similar) topics.
Upvotes: 2
Reputation: 334
By looking at the Integer class you may get a better idea why. Here is the code is below
/**
* Compares this object to the specified object. The result is
* <code>true</code> if and only if the argument is not
* <code>null</code> and is an <code>Integer</code> object that
* contains the same <code>int</code> value as this object.
*
* @param obj the object to compare with.
* @return <code>true</code> if the objects are the same;
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
Upvotes: 3
Reputation: 39485
This is the implementation of equals()
in Integer
:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
with that in mind, if the value
of i1 is 10, and the value
of i2 is also 10, then 10 == 10 would return true.
Upvotes: 2
Reputation: 2936
Because i1 and i2 have the same value. Integer.equals() is implemented like this:
public boolean equals(Object obj) {
return (obj instanceof Integer
&& intValue() == ((Integer) obj).intValue());
}
So i1 and i2 are Integers and they have the same value, so it will return true.
Upvotes: 4
Reputation: 229361
equals
is the value version of equality. Classes override this method to define what value equality means. For example, to see if two strings contain the same sequence of characters, you use the .equals()
method. If creating your own class, and, for example, you want to add it to a HashMap
, you would have to define both a hashCode()
and an equals()
method for it to work properly.
To see if two references point to the same memory location, use ==
.
Upvotes: 5
Reputation: 81
The equals method of the Integer class compares the int values that Integer wraps. As 10 is equal to 10, i1 and i2 are considered equal.
Upvotes: 3