Java clone() method

前端 未结 3 1234
慢半拍i
慢半拍i 2021-01-13 18:45

I read Effective Java by J.Bloch and here was wrote:

If you design a class for inheritance, be aware that if you choose not to provide a well-behave

相关标签:
3条回答
  • 2021-01-13 19:23

    Of course you can implement B.clone().

    The problem which J. Bloch refers to is (IIRC), that without a good A.clone() method, the private fields within A can not be cloned properly in B. Simple example:

    public class A {
      private String myText;
      public A (String myText) {
        this.myText = myText;
      }
      public String getExtendedText() {
        return "Hello something " + myText;
      }
    }
    
    public class B extends A implements Cloneable {
        private int someValue;
        // getter/setter
    
        public clone() {
            // how can you now provide a good clone with A.myText being cloned?
        }    
    }
    
    0 讨论(0)
  • 2021-01-13 19:30

    In your case yes you can override clone():

    public class A {
    }
    
    public class B extends A implements Cloneable {
    
        @Override
        public B clone() throws CloneNotSupportedException {
            return (B) super.clone();
        }
    }
    

    and still have an effective clone mechanism - you are therefore telling the truth when you state implements Cloneable.

    However, all that is needed to break that promise is to give A a private variable.

    public class A {
        private int a;
    }
    

    and now your promise is broken - unless A implements clone, in which case you can use super.clone():

    public class A {
    
        private int a;
    
        @Override
        public A clone() throws CloneNotSupportedException {
            A newA = (A) super.clone();
            newA.a = a;
            return newA;
        }
    }
    
    public class B extends A implements Cloneable {
    
        private int b;
    
        @Override
        public B clone() throws CloneNotSupportedException {
            B newB = (B) super.clone();
            newB.b = b;
            return newB;
        }
    }
    

    Essentially - as Joshua Bloch states - if you don't implement clone your sub-classes also cannot (generally).

    0 讨论(0)
  • 2021-01-13 19:39

    Cloneable and clone() are pretty much deprecated, so it doesn't matter anyway. However, since clone() is always supposed to call super.clone(), if a superclass implements it wrong, the subclass won't be able to fix it either.

    It has nothing to do with not being able to override clone(), it just won't result in a correct implementation.

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