Java clone () method

I read Effective Java from J.Bloch and wrote here:

If you create a class to inherit, keep in mind that if you choose not to provide a good protected clone method, it will be impossible for subclasses to implement Cloneable.

I have class A:

public class A{}

      

And class B, which extends class A:

public class B extends A implements Cloneable {

}

      

So, in this case, I cannot override the method clone()

? If so, how can you explain why.

+3


source to share


3 answers


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 efficient clone mechanism - that's why you're telling the truth when you point out implements Cloneable

.

However, all it takes to break that promise is to give the variable A

a private

.



public class A {
    private int a;
}

      

and now your promise is broken - if A doesn't implement 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 subclasses can't (usually) either.

+2


source


Cloneable

and are clone()

pretty outdated so it doesn't matter. However, since clone()

it must always call super.clone()

if the superclass does not execute it correctly, the subclass cannot fix it either.



It has nothing to do with what it cannot override clone()

, it just won't result in a correct implementation.

+1


source


You can of course implement B.clone()

.

The problem that Bloch refers to is (IIRC) that without a good method, the A.clone()

private fields inside A cannot be cloned correctly into B. A 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


source







All Articles