This tutorial explains about covariant return type in java and how we can override a method using covariant return type. The tutorial explains different aspect of covariant return type along with the advantages of using this.
What is Covariant return type in Java
If type(class) B can be used as a return type while overriding a method whose return type is A, then we call type B as a covariant type of type A. In java this is possible only when type B is a subclass of type A. So we can say all subtypes of a type are covariant type of that type. Covariant return type is applicable for non primitive types only.
Method overriding using covariant return type in Java
If a method in a class returns a non primitive type, then the same method in a subclass of that class can use the same non primitive type or a subclasses of that non primitive type as the return type to override that method.
Let's understand this by an example. In java we have a class Integer which extends a class Number which implicitly extends Object class,
so the inheritance structure looks like below.
If a class A has a method whose return type is an Object type, then the same method in a child class B(child of class A) can use Number or
Integer as return type to override that method because Number and Integer class are covariant of Object class.
Let's see this by the program given below :
Can we override a method which returns Object type with any non primitive type ?
Yes we can, since Object class is superclass of every class in java.
Java program of method overriding using covariant return type
classA {Objectprint() { System.out.println("print method of class A");return newObject(); } }classBextendsA {Integerprint() { System.out.println("print method of class B");return newInteger(2); }public static voidmain(String [] args) { B b =newB(); b.print(); A a =newB(); a.print(); } }
Output:
print method of class B print method of class B
As you can observe from the output, the print method in class B is overriding the print method of parent class A though the return type of child class method is Integer type It's
happening because java allows to use covariant return type while overriding the method.
Let's see one more program to understand it more clearly.
classA { }classBextendsA { }classCextendsA { }classD {publicA print() { System.out.println("print method of class D");return newA(); }publicA message() { System.out.println("message method of class D");return newA(); } }classEextendsD {publicB print() { System.out.println("print method of class E");return newB(); }publicC message() { System.out.println("message method of class E");return newC(); }public static voidmain(String [] args) { E e =newE(); e.print(); D d =newE(); d.message(); } }
Output:
print method of class E message method of class E
Here you can see the return type of print and message method of class D is A and we are able to override these methods in class E just by changing the return type as subclasses of class A. It's just because class B and class C are covariant type of class A since both are it's subtypes.
Rules of overriding a method using covariant return type
- The covariant return type is applicable only for non primitive or object types, not for primitive types.
- The return type of overriding method in child class can not be a return type which is parent of superclass method's return type. Doing so will result in compilation error.
- The overriding method's return type in child class should be either the same as the parent class method's return type or a subclass of that type.
Advantages of covariant return type in Java
- It gives you freedom to return more specific return type while overriding the method which may eliminates unnecessary downcasting from the super type to the subtype.
For example clone method of Object class can be overriden by implementing
Clonableinterface and the implementing class can return the object of its own type which will always be better than returningObjecttype. - It helps us in preventing runtime ClassCastException.


