This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm missing something on the following typical implementation of Cloneable's clone method:
Line 17 is my problem. The confusion is: why does the clone method get to directly set the bell instance variable of the copy even while it is private? Shouldn't it be forced to use a mutator method like everyone else? Is this a Cloneable-breaks-the-rules thing or am I missing something in plain sight?
From as I understand it, since copy is a Cat object, then Cat class can deal directly with its methods and fields, even the private ones. It's the same for when you want to do an equals(...) override: The current object has the ability to directly see and manipulate the object passed as a paramter (if it's the same type).
However it's also true that clone() breaks several rules. In particular, the clone() method in Object (which is the one you get when you access super.clone() here) is quite capable of copying private fields from any object in any class - provided that class implements Cloneable. This despite the face that it's a method of class Object, which should (in theory) have no access to private fields of other classes. Except that Java's creators decided to bend/break the rules here. They can do that.
This means that line 17 is completely unnecessary. The "bell" field was already copied by super.clone(). No need to copy it again.
But if, for some reason, you do find it necessary to access a private field of an instance of a given class, from a different instance of the same class... you can do that. Because that's how "private" has always been defined, in Java. Private to the class, not private to an instance. As EFH said.
One note: don't return null when you catch those CloneNotSupportedExceptions. Since your classes implement Cloneable that exception should never occur, so it's a better idea to throw an error:
That's how Sun does it as well.