Can overridden methods differ in return type? Can overridden methods differ in return type? java java

Can overridden methods differ in return type?


Java supports* covariant return types for overridden methods. This means an overridden method may have a more specific return type. That is, as long as the new return type is assignable to the return type of the method you are overriding, it's allowed.

For example:

class ShapeBuilder {    ...    public Shape build() {    ....}class CircleBuilder extends ShapeBuilder{    ...    @Override    public Circle build() {    ....}

This is specified in section 8.4.5 of the Java Language Specification:

Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.

A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:

  • If R1 is void then R2 is void.

  • If R1 is a primitive type, then R2 is identical to R1.

  • If R1 is a reference type then:

    • R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or

    • R1 = |R2|

("|R2|" refers to the erasure of R2, as defined in §4.6 of the JLS.)


* Prior to Java 5, Java had invariant return types, which meant the return type of a method override needed to exactly match the method being overridden.


Yes it may differ but there are some limitations.

Before Java 5.0, when you override a method, both parameters and return type must match exactly. Java 5.0 it introduces a new facility called covariant return type. You can override a method with the same signature but return a subclass of the object returned.

In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass.


Yes, if they return a subtype. Here's an example:

package com.sandbox;public class Sandbox {    private static class Parent {        public ParentReturnType run() {            return new ParentReturnType();        }    }    private static class ParentReturnType {    }    private static class Child extends Parent {        @Override        public ChildReturnType run() {            return new ChildReturnType();        }    }    private static class ChildReturnType extends ParentReturnType {    }}

This code compiles and runs.