Why is #clone() not in the Cloneable interface?

后端 未结 3 2026
盖世英雄少女心
盖世英雄少女心 2021-01-31 20:13

I was reading up on performing a deep-copy of an array correctly, however I was confused about how the #clone() is implemented. It is a member of the java.lan

相关标签:
3条回答
  • 2021-01-31 20:29

    clone() method is unnecessary, every object could invoke Object.clone method by reflect, so an object can be cloned depends on whether to implement Cloneable interface. This is for a security reason. You can simply clone an object which implements Cloneable by this util:

    @SuppressWarnings("unchecked")
    public static <T extends Cloneable> T clone(Cloneable obj) {
        T rtn = null;
        try {
            Method method = Object.class.getDeclaredMethod("clone");
            method.setAccessible(true);
            rtn = (T) method.invoke(obj);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return rtn;
    }
    
    0 讨论(0)
  • 2021-01-31 20:35

    To deal with creating the clone and basic field copying, clone needs to inherit a method implementation. A Cloneable class can appear anywhere in the hierarchy, and may need to extend a specific superclass to do its primary job. The only superclass from which all possible Cloneable classes can inherit implementation is Object.

    Cloning was defined long before generics.

    0 讨论(0)
  • 2021-01-31 20:36

    The cloning contract in Java dictates that each clone implementation must first obtain the cloned instance from super.clone(). This creates a chain that always ends with the call to Object.clone, and that method contains "magical" native-level code that makes a binary copy of the underlying raw struct which represents the Java object. If this mechanism didn't exist, clone would fail to be polymorphic: the Object.clone method produces an instance of whatever class it is called on; this cannot be reproduced without native code.

    This is why the Object.clone method could not have been avoided. Cloneable could have contained a clone method, but it would create issues regarding the throws clause. The way it stands you are free to declare clone with no declared exceptions, or to declare arbitrary exceptions. This flexibility would not be possible if the method was already declared in the interface.

    Bear in mind that Generics would be of little use for cloning: imagine protected T clone() in Object: where would T come from? Would we need Object<T> and force each and every class in Java universe to be parameterized on itself, and all this just to make this semi-deprecated mechanism work a tiny bit better? Keep also in mind that this code is perfectly legal:

    public class TheMightyOne implements Cloneable {
       @Override public TheMightyOne clone() {
         return (TheMightyOne) super.clone();
       }
    }
    

    You can call it:

    TheMightyOne one = new TheMightyOne();
    TheMightyOne two = one.clone(); // do downcasts needed
    
    0 讨论(0)
提交回复
热议问题