In Java, any object whether it is predefine or customized the most commonly required methods are encapsulated into a separate class which is nothing but object class.
As object class acts as root (or) parent (or) super for all java classes, by default its methods are available to every java class.
Note: If our class doesn't extend any other class then it is the direct child class of object If our class extends any other class then it is the indirect child class of Object.
The following is the list of all methods present in java.lang Object class :
public native int hashCode(); public boolean equals(Object o); protected native Object clone()throws CloneNotSupportedException; public final Class getClass(); protected void finalize()throws Throwable; public final void wait() throws InterruptedException; public final native void wait()throws InterruptedException; public final void wait(long ms,int ns)throws InterruptedException; public final native void notify(); public final native void notifyAll();
public String toString();
toString() method
We can use this method to get a string representation of an object.
Whenever we are trying to print any object reference internally toString() method will be executed.
If our class doesn't contain the toString() method then Object class toString() method will be executed.
{ String name; int rollno; Student(String name, int rollno) { this.name=name; this.rollno=rollno; } public static void main(String args[]){ Student s1=new Student("saicharan",101); Student s2=new Student("ashok",102); System.out.println(s1); System.out.println(s1.toString()); System.out.println(s2); } } Output: Student@3e25a5 Student@3e25a5 Student@19821f
class Student
5). In the above program Object class toString() method got executed which is implemented as follows.
return getClass().getName() + "@" + Integer.toHexString(hashCode());
public String toString() {
}
here getClass().getName() => classname@hexa_decimal_String_representation_of_hashCode
6). To provide our own String representation we have to override toString() method in our class. Ex: For example whenever we are trying to print student reference to print his a name and roll no we have to override toString() method as follows.
return name+"........"+rollno; }
public String toString(){
7). To provide our own String representation we have to override toString() method in our class. Ex: For example whenever we are trying to print student reference to print his a name and roll no we have to override toString() method as follows
return name+"........"+rollno;
public String toString(){
public String toString(){ return "Test"; } public static void main(String[] args){ Integer i=new Integer(10); String s=new String("ashok"); Test t=new Test(); System.out.println(i); System.out.println(s); System.out.println(t); } } Output: 10 ashok Test
class Test{
hashCode() method
- For every object, JVM will generate a unique number which is nothing but hashCode.
- Jvm will use hashCode while saving objects into hashing related data structures like HashSet, HashMap, and Hashtable, etc.
- If the objects are stored according to hashCode searching will become very efficient (The most powerful search algorithm is hashing which will work based on hashCode).
- If we didn't override hashCode() method then the Object class hashCode() method will be executed which generates hashCode based on the address of the object but it doesn't mean hashCode represents the address of the object.
- Based on our programming requirement we can override hashCode() method to generate our own hashcode.
- Overriding hashCode() method is said to be proper if and only if for every object we have to generate a unique number as hashcode for every object.
{ public int hashCode() { return 100; } }
class Student
It is an improper way of overriding hashCode() method because for every object we are generating the same hashcode.
{ int rollno; public int hashCode() { return rollno; } }
class Student
It is a proper way of overriding hashcode() method because for every object we are generating a different hashcode.
toString() method vs hashCode() method:
{ int i; Test(int i) { this.i=i; } public static void main(String[] args){ Test t1=new Test(10); Test t2=new Test(100); System.out.println(t1); System.out.println(t2); } } Object==>toString() called. Object==>hashCode() called.
class Test
In this case Object class toString( ) method got executed which is internally calls Object class hashCode( ) method.
int i; Test(int i){ this.i=i; } public int hashCode(){ return i; } public static void main(String[] args){ Test t1=new Test(10); Test t2=new Test(100); System.out.println(t1); System.out.println(t2); }} Object==>toString() called. Test==>hashCode() called.
class Test{
In this case Object class toString( ) method got executed which is internally calls Test class hashCode( ) method.
{ int i; Test(int i) { this.i=i; } public int hashCode(){ return i; } public String toString() { return i+""; } public static void main(String[] args){ Test t1=new Test(10); Test t2=new Test(100); System.out.println(t1); System.out.println(t2); } } Output: 10 100
class Test
In this case Test class toString() method got executed.
Note : 1). if we are giving the opportunity to Object class toString() method it internally calls hashCode() method. But if we are overriding toString() method it may not call hashCode() method.
2). We can use the toString() method while printing object references and we can use the hashCode() method while saving objects into HashSet or Hashtable or HashMap.
equals() method
We can use this method to check the equivalence of two objects.
If our class doesn't contain .equals() method then object class .equals() method will be executed which is always meant for reference comparison[address comparison]. i.e., if two references pointing to the same object then only .equals( ) method returns true .
{ String name; int rollno; Student(String name,int rollno) { this.name=name; this.rollno=rollno; } public static void main(String[] args){ Student s1=new Student("vijayabhaskar",101); Student s2=new Student("bhaskar",102); Student s3=new Student("vijayabhaskar",101); Student s4=s1; System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3)); System.out.println(s1.equals(s4)); }} Output: False False True
class Student
image001
In the above program Object class .equals() method got executed which is always meant for reference comparison that is if two references pointing to the same object then only .equals(() method returns true.
In object class .equals() method is implemented as follows which is meant for reference comparison.
return (this == obj); }
public boolean equals(Object obj) {
Based on our programming requirement we can override .equals() method for content comparison purposes.
When ever we are overriding .equals() method we have to consider the following things :
- Meaning of content comparison i.e., whether we have to check the names are equal (or) roll numbers (or) both are equal.
- If we are passing different types of objects (heterogeneous object) our .equals() method should return false but not ClassCastException i.e., we have to handle ClassCastException to return false.
- If we are passing null argument our .equals() method should return false but not NullPointerException i.e., we have to handle NullPointerException to return false.
The following is the proper way of overriding .equals() method for content comparison in Student class
{ String name; int rollno; Student(String name,int rollno) { this.name=name; this.rollno=rollno; } public boolean equals(Object obj) { try{ String name1=this.name; int rollno1=this.rollno; Student s2=(Student)obj; String name2=s2.name; int rollno2=s2.rollno; if(name1.equals(name2) && rollno1==rollno2) { return true; } else return false; } catch(ClassCastException e) { return false; } catch(NullPointerException e) { return false; } } public static void main(String[] args){ Student s1=new Student("vijayabhaskar",101); Student s2=new Student("bhaskar",102); Student s3=new Student("vijayabhaskar",101); Student s4=s1; System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3)); System.out.println(s1.equals(s4)); System.out.println(s1.equals("vijayabhaskar")); System.out.println(s1.equals("null")); } } Output: False True True False False
class Student
Simplified version of .equals() method
try{ Student s2=(Student)o; if(name.equals(s2.name) && rollno==s2.rollno){ return true; } else return false; } catch(ClassCastException e) { return false; } catch(NullPointerException e) { return false; } }
public boolean equals(Object o){
More simplified version of .equals() method :
if(this==o) return true; if(o instanceof Student) { Student s2=(Student)o; if(name.equals(s2.name) && rollno==s2.rollno) return true; else return false; } return false; }
public boolean equals(Object o) {
String name; int rollno; Student(String name,int rollno) { this.name=name; this.rollno=rollno; } public boolean equals(Object o) { if(this==o) return true; if(o instanceof Student) { Student s2=(Student)o; if(name.equals(s2.name) && rollno==s2.rollno) return true; else return false; } return false; } public static void main(String[] args){ Student s=new Student("vijayabhaskar",101); Integer i=new Integer(10); System.out.println(s.equals(i)); } } Output: False
class Student {
To make .equals() method more efficient we have to place the following code at the top inside .equals() method. if(this==o) return true;
image002
If 2 references pointing to the same object then .equals() method return true directly without performing any content comparison this approach improves performance of the systemtable 1) String s1 = new String("ashok"); String s2 = new String("ashok"); System.out.println(s1==s2); //false System.out.println(s1.equals(s2) ); //true 2)In String class .equals( ) is overridden for content comparision hence if content is same .equals( ) method returns true , even though ths objects are different. 1) StringBuffer s1 = new StringBuffer("ashok"); StringBuffer s2 = new StringBuffer("ashok"); System.out.println(s1==s2); //false System.out.println(s1.equals(s2) ); //false 2)In StringBuffer class .equals( ) is not overriden for content comparision hence Object class .equals( ) will be executed which is meant for reference comparision , hence if objects are different .equals( ) method returns false , even though content is same.
In String class , Wrapper classes and all collection classes .equals( ) method is overriden for content comparision
Relationship between .equals() method and ==(double equal operator) :
- If r1==r2 is true then r1.equals(r2) is always true i.e., if two objects are equal by == operator then these objects are always equal by .equals( ) method also.
- If r1==r2 is false then we can't conclude anything about r1.equals(r2) it may return true (or) false
- If r1.equals(r2) is true then we can't conclude anything about r1==r2 it may returns true (or) false.
- If r1.equals(r2) is false then r1==r2 is always false.
Differences between == (double equal operator) and .equals() method?
== (double equal operator) .equals() method 1). It is an operator applicable for both primitives and object references. 2). It is a method applicable only for object references but not for primitives. 1).In the case of primitives == (double equal operator) meant for content comparison, but in the case of object references == operator meant for reference comparison. By default .equals() method present in object class is also meant for reference comparison. 20. We can't override== operator for content comparison in object references. We can override .equals() method for content comparison. 1). If there is no relationship between argument types then we will get compile time error saying incompatible types.(relation means child to parent or parent to child or same type) 2)If there is no relationship between argument types then .equals() method simply returns false and we won't get any compile time error and runtime error. 1). For any object reference r, r==null is always false. 2). For any object reference r, r.equals(null) is also returns false.
String s = new String("ashok");
StringBuffer sb = new StringBuffer("ashok");
System.out.println(s == sb); // CE : incomparable types : String and StringBuffer
System.out.println(s.equals(sb)); //false
Note:
in general we can use == (double equal operator) for reference comparison whereas .equals() method for content comparison.
Contract between .equals() method and hashCode() method:
- If 2 objects are equal by .equals() method compulsory their hashcodes must be equal (or) same. That is If r1.equals(r2) is true then r1.hascode()==r2.hashcode( ) must be true.
- If 2 objects are not equal by .equals() method then there are no restrictions on hashCode() methods. They may be same (or) may be different. That is If r1.equals(r2) is false then r1.hashCode()==r2.hashCode() may be same (or) may be different.
- If hashcodes of 2 objects are equal we can't conclude anything about .equals() method it may returns true (or) false. That is If r1.hashCode()==r2.hashCode() is true then r1.equals(r2) method may returns true (or) false.
- If hashcodes of 2 objects are not equal then these objects are always not equal by .equals() method also. That is If r1.hashCode()==r2.hashCode() is false then r1.equals(r2) is always false.
- To maintain the above contract between .equals() and hashCode() methods whenever we are overriding .equals() method compulsory we should override hashCode() method. Violation leads to no compile time error and runtime error but it is not good programming practice.
Consider the following person's class.
String name; int age; Person(String name,int age) { this.name=name; this.age=age; } public boolean equals(Object o) { if(this==o) return true; if(o instanceof Person) { Person p2=(Person)o; if(name.equals(p2.name) && age==p2.age) return true; else return false; } return false; } public static void main(String[] args){ Person p1=new Person("vijayabhaskar",101); Person p2=new Person("vijayabhaskar",101); Integer i=new Integer(102); System.out.println(p1.equals(p2)); System.out.println(p1.equals(i)); } } Output: True False
class Person {
Which of the following is valid?
1). If hash Codes of 2 objects are not equal then .equals() method always return false. (valid)
int i; Test(int i) { this.i=i; } public int hashCode() { return i; } public String toString() { return i+""; } public static void main(String[] args) { Test t1=new Test(10); Test t2=new Test(20); System.out.println(t1.hashCode());//10 System.out.println(t2.hashCode());//20 System.out.println(t1.hashCode()==t2.hashCode());//false System.out.println(t1.equals(t2));//false } }
class Test {
2). If 2 objects are equal by == operator then their hash codes must be same. (valid)
class Test {
int i;
Test(int i) {
this.i=i;
}
public int hashCode() {
return i;
}
public String toString() {
return i+"";
}
public static void main(String[] args) {
Test t1=new Test(10);
Test t2=t1;
System.out.println(t1.hashCode());//10
System.out.println(t2.hashCode());//10
System.out.println(t1==t2);//true
}
}
3). If == operator returns false then their hash codes(may be same (or) may be different) must be different.(invalid)
int i; Test(int i) { this.i=i; } public int hashCode() { return i; } public String toString() { return i+""; } public static void main(String[] args) { Test t1=new Test(10); Test t2=new Test(10); System.out.println(t1.hashCode());//10 System.out.println(t2.hashCode());//10 System.out.println(t1==t2);//false } }
class Test {
4). If hashcodes of 2 objects are equal then these objects are always equal by == operator also.(invalid)
Clone () method:
The process of creating exactly the duplicate objects is called cloning.
The main objective of cloning is to maintain backup purposes.(i.e., if something goes wrong we can recover the situation by using a backup copy.)
We can perform cloning by using the clone() method of the Object class.
Example:class Test implements Cloneable
{
int i=50;
int j=100;
public static void main(String[] args)throws CloneNotSupportedException
{
Test t1=new Test();
Test t2=(Test)t1.clone();
t2.i=1001;
t2.j=9001;
System.out.println(t1.i+"---------------"+t1.j);
System.out.println(t2.i+"---------------"+t2.j);
}
}
Output:
50---------------1001
888---------------9001
image4
- We can perform cloning only for Cloneable objects.
- An object is said to be Cloneable if and only if the corresponding class implements the Cloneable interface.
- Cloneable interface present in java.lang package and does not contain any methods. It is a marker interface where the required ability will be provided automatically by the JVM.
- If we are trying to perform cloning or non-clonable objects then we will get RuntimeException saying CloneNotSupportedException.
You can see more details of shallow and Deep Cloning here.
getClass() method
This method returns the runtime class definition of an object.OutputExample:
public static void main(String[] args)throws CloneNotSupportedException { Object o=new String("ashok"); System.out.println("Runtime object type of o is :"+o.getClass().getName()); } } Output: Runtime object type of o is: java.lang. String Ex : To print Connecton interface implemented vendor specific class name . System.out.println(con.getClass( ).getName( ) );
class Test implements Cloneable {
finalize( )
Just before destroying an object, GC calls finalize( ) method to perform CleanUp activities.
wait( ) , notify( ) , notifyAll( )
We can use these methods for inter thread communication.you can get in detail for wait() , notify() , notifyAll()
That's it!!! We have seen Object class methods in Java.
0 Comments
Post a Comment