This week's book giveaway is in the Mac OS forum. We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line! See this thread for details.
I think a new interface with clone() method clearly defined would make the world a better place:
1. more intuitive, if you want to clone a object, you must implement the interface and all its methods. 2. with generic return type, client code doesn't need casting.
Then question is why there is no such new interface? Take Comparable for example, it has been enhanced by generic typing.
OK, so that other guy knows Java better than I do, but I bet he can't speak Wuhanese(a Chinese Dialect) like me.
First of all, the clone() method is already "generic". If you read the documentation, it says something like the return type being equal to the formal type of the instance you're calling it on. If you think about it, this is more than you're getting than you would with a generic interface. With a generic interface the return type for a particular class would always be the same. With the clone() method as it is, you get the formal type.
So it's perfectly legal to do stuff like this:I agree however with the fact that the Cloneable interface should have had a clone() method declaration.
The problem is that the clone() mechanism can not be enforced by the language as it is. The clone() method uses a lot of magic* to achieve what it does, so it's no matter of simply rewriting a class. The language designers would actually have to either add new features to the language itself, or write more magic to make a new clone() mechanism. This is a lot of work, and not really necessary since there is already a clone facility.
*Magic here means things that happen outside the language. The clone() method probably uses native code to copy memory blocks. I don't know for sure, I have never actually investigated the method in depth.
Leon Omk wrote:Then question is why there is no such new interface? Take Comparable for example, it has been enhanced by generic typing.
Not absolutely sure, but I suspect it has something to do with the fact that the Object class itself isn't generic. Otherwise, you could argue the same thing about equals(): Why haven't they added a generic Equatable interface that defines both equals() and hashCode()? It'd save an awful lot of the current faffing around that you have to do inside equals() methods at the moment.
Secondly, there is a fairly easy workaround with Cloneable: use a copy constructor or factory (the factory could even be used with a Copyable interface of your own).
Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
There is no need to add generics for the clone method. Java 5.0 introduced the "covariant return type", which means that the return type of an overridden method no longer needs to be the same as that of the method it overrides, but it can now be a sub type. Even without generics you can create a class and give it a clone() method with that class itself as its return type:
This is what Stephan's example implicitly does as well.
I wish that the release of Java 5.0 would have added a lot more covariant return types for clone methods. It's one of my biggest complaints. However, I also see the reason. Suppose you were using Java 1.4, and created a sub class of java.util.Date:
Now suppose Java 5.0 would have changed the return type of java.util.Date's clone() method to Date. Your MyDate class would all of a sudden no longer compile, because the return type would no longer be compatible with Date.
So for existing code it's not a good idea to change the return type of clone() for non-final classes, for new classes you should definitely change it to the class itself.