Consider this class and we will provide an equals method for it.
Class A{
String test;
Integer i;
public A(String str, Integer i){
this.test = str; this. i = i;
}
@Override
public boolean equals(Object obj) {
if (obj == null)return false;
if (obj instanceof A) {
A a= (A) obj;
if (this.test==a.test && this.i==a.i)
return true;
return false;
}
else
return false;
}}}
Now consider Object creation for A class
A a = new (new String("testing"), new Integer(1));
A a1 = new (new String("testing"), new Integer(1));
Both objects a and a1 have same data values for String test and Integer i now when we call
a==a1 --> Result is false which is correct because a and a1 are two references pointing to two different memory locations. And "==" checks for object references and not equality of contents, Its the responsibility of class equals method to declare 2 objects are equal when they have same content. So calling
a.equals(a1) --> This also returns false. Dangerously wrong. Here there are 2 culprits:-
1. The creation of Object
A a = new A(new String("test"), new Integer(1) );
A a1 = new A(new String("test"), new Integer(1) );
Both objects a and a1 creates new String and new Integer, which will never be equal when we call "==" (reference check). Hence result in a false comparison. This can be corrected by creating objects as:-
A a = new A("test",1);
A a1 = new A("test",1);
Now a.equals(a1) will result in true. So your caller should be aware, while creating Objects.
2. Equals should be Overriden to check contents, instead depending on the object/caller. Now modifying code so that it can work in both the case of object creation.
if (this.test.equals(a.test) && this.i.equals(a.i)).
now if we invoke a.equals(a1) will result in true, in either case. The reason that String class equals compare exact character sequence which is data content and Integer class equals compares the exact value in the implementation.
So calling equals on the primitive wrappers or String class will ensure that it will compare data sequences.
As part of good practice avoid using wrapper classes as member variable, use primitves for which "==" will check for code values, even if the object creation happens as new Integer(1) in constructor. This will again fall in the category of unboxing Integer to int.
Friday, September 11, 2009
Subscribe to:
Post Comments (Atom)

nicely explained...as usual :)
ReplyDelete