1

I'm reading carefully Effective Java (by Joshua Bloch) and I found the following sentence on cloning:

If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.

I'm a little bit confused, because in my little test:

public class Cloning {

    public static void main(String[] args) throws CloneNotSupportedException {

        Woman woman1 = new Woman("Marie Curie-Sklodowska", 33, "Physics");
        Woman woman2 = (Woman) woman1.clone();
    }

    static abstract class Person {
        protected String name;
        protected int age;

        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

    static class Woman extends Person implements Cloneable {

        private String field;

        Woman(String name, int age, String field) {
            super(name, age);
            this.field = field;
        }

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

I'm not getting any error. I think, I do not understand the sentence correctly. Could someone please explain, what the author had in mind?

agienka
  • 396
  • 1
  • 2
  • 11
  • Override `Person.clone()` and make it throw `CloneNotSupportedException` explicitly. Then it won't work. – Andy Turner Nov 13 '17 at 22:43
  • 2
    @AndyTurner That sounds more like choosing to provide an ill-behaved `clone` method. – shmosel Nov 13 '17 at 22:48
  • 2
    @AndyTurner The question definitely seems like a duplicate, but I'm not getting the answer at all. As far as I can tell, `clone()` works fine with private fields in the superclass. – shmosel Nov 13 '17 at 22:59
  • 1
    Hm, I'm reading the post on the same topic, but the accepted answer is not clear to me too. It states, that making private fields 'breaks the promise', but I've tried with private fields - and it made no difference. The cloned object is the same. So my question might be the clone, but the original one doesn't contain satisfying answer. – agienka Nov 13 '17 at 23:04
  • @nibsa The accepted answer is wrong. There is nothing in any of the answers there that requires anything more than what `Object.clone()` does. I don't know what Bloch is talking about here, unless it is deep-copying. – user207421 Nov 13 '17 at 23:28
  • 1
    I'm reopening the question because I don't believe the [duplicate](https://stackoverflow.com/q/30078647/1553851) was answered satisfactorily. – shmosel Nov 14 '17 at 07:00

1 Answers1

0

If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone() method, it will be impossible for subclasses to implement Cloneable.

He's wrong. They can. Consider:

public class A
{
    private int fieldA;
}

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

B.clone() will return a perfect copy of the instance of B it is invoked on, including A.fieldA. Refuted by counter-example: QED

[I'm aware that this clone() should not really be declared to throw CloneNotSupportedException but it makes the demonstration simpler.]

This all is very curious, because a couple of sentences earlier he has just said:

some programmers simply choose never to override the clone() method

and

classes designed for inheritance should not implement it [Cloneable]

What's even more curious is that the first sentence above is the final sentence in the entire section, and is completley unsupported by either argument or example, unless the entire section is intended to prove it, which it doesn't. The whole section is all so confused that it is difficult to make out exactly what is being claimed. Cloning isn't as difficult to understand or implement as he makes out. Nor is it important. I haven't used it in serious code in 20 years of Java, or so-called 'copy constructors' either.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I was expecting that there is something wrong with the summary for the section on cloning. But I think it reached it's goal - I'm discouraged enough to use the `clone()` method and `Cloneable` interface. Thanks for the answer! – agienka Nov 18 '17 at 08:45