Search code examples
javajavapcovariant-return-types

Object.clone() in javap when using covariant return types in Java


I am reading about covariant return types in Java. I wrote the following code:

A parent class:

package other;

public class Super implements Cloneable {

    @Override
    public Super clone() throws CloneNotSupportedException {
        return (Super) super.clone();
    }

}

A child class:

package other;

public class Sub extends Super {

    @Override
    public Sub clone() throws CloneNotSupportedException {
        return (Sub) super.clone();
    }
}

How I use it:

package com.sample;

import other.Sub;
import other.Super;

public class Main {

    public static void main(String[] args) throws Exception {
        Super aSuper = new Super();
        Super bSuper = aSuper.clone();
        System.out.println(aSuper == bSuper); // false

        Sub aSub = new Sub();
        Sub bSub = aSub.clone();
        System.out.println(aSub == bSub); // false
    }
}

If it's OK to return a subtype when overriding a method (as you see, that's what I do with clone() in Super and Sub), why do I see Object.clone in Super and Sub when I run javap -p Super.class and javap -p Sub.class, respectively?

The result of javap -p Super.class:

Compiled from "Super.java"
public class other.Super implements java.lang.Cloneable {
  public other.Super();
  public other.Super clone() throws java.lang.CloneNotSupportedException;
  public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
}

The result of javap -p Sub.class:

Compiled from "Sub.java"
public class other.Sub extends other.Super {
  public other.Sub();
  public other.Sub clone() throws java.lang.CloneNotSupportedException;
  public other.Super clone() throws java.lang.CloneNotSupportedException;
  public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
} 

Solution

  • clone method belongs to class Object We can override this method .But in order to call this method Java Runtime requires us to indicate that this class will clone its object using clone method which makes a field-for-field copy of instances of that class .

    This indication is done buy using marker interface Cloneable (marker interfaces have no method they are used just to indicate a specific thing to compiler and JVM) .

    In class Super clone() method you are calling super.clone() That is nothing but call to Object.clone() method because Object is direct super class of Super .

    That explains why you see java.lang.Object clone() when you use javap

    for more info read

    Cloneable ref