Effective Java: Analysis of the clone() method

前端 未结 5 638
南笙
南笙 2020-12-09 04:48

Consider the following from Effective Java Item 11 (Override clone judiciously) where Josh Bloch is explaining what is wrong with the clone() contract .

相关标签:
5条回答
  • 2020-12-09 04:53

    The contract for clone specifies that "By convention, the returned object should be obtained by calling super.clone". If your class is not final and you return something obtained with a constructor invocation, calling super.clone() from a subclass will not return the expected result (first of all, the type of the returned object will not be the type of the subclass, as the native clone() method would return).

    0 讨论(0)
  • 2020-12-09 05:03

    If a class is not final, clone has to return the most derived class for which it was called. That can't work with a constructor, because clone doesn't know which one to call. If a class is final, it can't have any subclasses, so there's no danger in calling its constructor when cloning.

    0 讨论(0)
  • 2020-12-09 05:04

    It's because typical implementations of clone() look like this:

    public class MyClass implements Cloneable {
      protected Object clone() {
        MyClass cloned = (MyClass) super.clone();
        // set additional clone properties here
      }
    }
    

    In this way you can inherit the cloning behavior from your superclass. It's widely assumed that the result of a clone() operation will return the correct instance type based on the object it was called on. Ie. this.getClass()

    So if a class is final, you don't have to worry about a subclass calling super.clone() and not getting the right object type back.

    public class A implements Cloneable {
        public Object clone() {
           return new A();
        }
    }
    
    
    public class B extends A {
        public Object clone() {
           B b = (B)super.clone(); // <== will throw ClassCastException
        }
    }
    

    But, if A is final, no one can extend it, and thus it's safe to use a constructor.

    0 讨论(0)
  • 2020-12-09 05:11

    A class doesn't have to provide its own implementation of clone in order to be cloneable. It can delegate that to its cloneable superclass. Here comes the catch: clone must always return an instance of the same class as the instance it is called on. That is impossible to achieve in the described case if an explicit constructor is called. If the class overridng clone is final, on the other hand, this would be fine.

    0 讨论(0)
  • 2020-12-09 05:12

    See Jorado answer. This is the explanation. In additional clone has problem in final fields see : http://en.wikipedia.org/wiki/Clone_%28Java_method%29#clone.28.29_and_final_fields

    You also should read Josh interview on clone in: http://www.artima.com/intv/bloch13.html

    0 讨论(0)
提交回复
热议问题