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 String toString();
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();

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.

class Student
{ 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

5). In the above program Object class toString() method got executed which is implemented as follows.

public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

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.

public String toString(){
return name+"........"+rollno; }

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

public String toString(){
return name+"........"+rollno;
class Test{
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

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.
class Student
{ public int hashCode() { return 100; } }

It is an improper way of overriding hashCode() method because for every object we are generating the same hashcode.

class Student
{ int rollno; public int hashCode() { return rollno; } }

It is a proper way of overriding hashcode() method because for every object we are generating a different hashcode.

toString() method vs hashCode() method:

class Test
{ 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.

In this case Object class toString( ) method got executed which is internally calls Object class hashCode( ) method.

class Test{
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.

In this case Object class toString( ) method got executed which is internally calls Test class hashCode( ) method.

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=new Test(100); System.out.println(t1); System.out.println(t2); } } Output: 10 100

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 .

class Student
{ 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

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.

public boolean equals(Object obj) {
return (this == 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

class Student
{ 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

Simplified version of .equals() method

public boolean equals(Object o){
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; } }

More simplified version of .equals() method :

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; }
class Student {
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

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 system

table 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.

class Person {
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

Which of the following is valid?

1). If hash Codes of 2 objects are not equal then .equals() method always return false. (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=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 } }

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)

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=new Test(10); System.out.println(t1.hashCode());//10 System.out.println(t2.hashCode());//10 System.out.println(t1==t2);//false } }

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:

class Test implements Cloneable {
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( ) );

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.