Why to override clone method in Java

2019-01-26 06:40发布

问题:

I am confused regarding overriding clone method in the class for which I want cloned object.

Object class has protected object method and as per the protected behavior which is When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class.

As every class in Java extends from Object, so it should have clone method but still we are forced to override clone. Why is it required?

Also, I have read at some places to override the clone object and make it public. I wonder, why is it so?

All answers are welcome.

回答1:

As every class in Java extends from Object, so it should have clone method but still we are forced to override clone

No you are not forced to override the clone method. In inheritance, when you inherit a class, you are not forced to override it's method. Its modifier being public or protected doesn't make much of a difference. However, if you want to invoke a method directly on super class reference, then that method has to be public. Protected methods are accessible only through inheritance. That is you can only access them through subclass reference. Or if you override the method, you can access them through super keyword.

Having said that, you should not override clone method, as it is broken. Because, for a class to be cloned, you need to implement the Cloneable interface. And then your class uses the clone method of Object class instead. Because, Cloneable interface doesn't exactly have any method for cloning. It would be a better option to use Copy Constructor instead.

public class A {
   private int data;
   public A() {
   }

   public A(A a) {
      this.data = a.data;
   }
}

For more details, I would suggest to go through this chapter of Joshua Bloch's Effective Java, which covers all aspects of using clone method.

Effective Java- Item # 11 - Override clone judiciously



回答2:

I'd recommend reading Joshua Bloch's Effective Java 2nd edition. It has a good chapter discussing clone.

I would not advise doing this. I consider this a JDK 1.0 mistake. The book will make that clearer.

I'd recommend writing a copy constructor instead to get what you want:

public class Foo {
    private String name;
    public Foo(String name) { this.name = name; }
    public Foo(Foo f) { this.name = f.name; }  // copy ctor here.
}


回答3:

In many cases it's not clear what a cloned object should be and how it should behave, so if you want your class to be clonable you have to say so explicitly by overriding clone and making it public.

Cases where clone might not make sense include classes that represent some resource, like a network connection or a synchronization lock. If these objects could be cloned it's not clear how the clone should behave. For example, does the clone of a network connection have a TCP/IP connection of its own or does it somehow use the existing one?



回答4:

Clone is Protected method in Object class so it is accessible to you inside class.

About access- When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class.

I see some misconceptions about clone method

  1. clone() method is protected inside Object class so you can not call clone() outside of class. e.g. child.clone() unless you override it and make access public
  2. Cloneable is marker interface and if you do not mark class Cloneable then you will get CloneNotSupportedException if you call clone() method
  3. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.
  4. By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().

Method signature is below

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

References :

  1. Object#clone()
  2. Cloneable


回答5:

    Why we do override clone() in cloning process?
    //clone() in Object class is protected
    package java.lang;


    protected native Object clone()
            throws CloneNotSupportedException;

    java.lang is default import in our java applications.

Note: If parent and sub class are both in same package then the methods in parent class are directly accessible. If they are in different package,then in subclass we have to override the parent class methods to use.

    Note:Object class is in java.lang package,we are using it in different package,so we have to override the clone() which is protected in Object class


first we will look into Protected method behavior.here is sample program to understand this
    //this class is in com.anusha.clonetrial
    package com.anusha.clonetrial;

    public class A {

        public A()
        {

        }
        protected void disp1()
        {
            System.out.println("class a");
        }
        protected void disp2()
        {
            System.out.println("class a");
        }
    }
    //below classes are in com.anusha.Test
    package com.anusha.Test;
    import com.anusha.clonetrial.A;


    class AA {


        protected void disp1()
        {
            System.out.println("class aa");
        }

        protected void disp2()
        {
            System.out.println("class aa");
        }
    }

    //class B derived from AA which is present in the same package
    class B extends AA
    {

        void show()
        {


            System.out.println("class b");
        }
    }

    //class C derived from A which is present in the different package

    class C extends A
    {

        @Override
        protected void disp1()
        {
            super.disp1();
        }
        void show()
        { 
            System.out.println("class c");
        }
    }

    package com.anusha.Test;




    public class CloneTest {


        public static void main(String[] args) {
            B b=new B();
            C c=new C();
            b.disp1();
            b.disp2();
            c.disp1();
            c.disp2();//gives error because it is not overridden.


        }

    }


标签: java clone