The short answer to "why isn't Cloneable
deprecated?" (or indeed, why isn't X
deprecated, for any X
) is that there hasn't been much attention paid to deprecating them.
Most things that have been deprecated recently were deprecated because there is a specific plan to remove them. For example, the addPropertyChangeListener
and removePropertyChangeListener
methods of LogManager were deprecated in Java SE 8 with the intention of removing them in Java SE 9. (The reason is that they unnecessarily complicated module interdependencies.) Indeed, these APIs have already been removed from early JDK 9 development builds. (Note that similar property change listener calls were also removed from Pack200
; see JDK-8029806.)
No such similar plan exists to for Cloneable
and Object.clone()
.
A longer answer would involve discussing further questions, such as what one might expect to happen to these APIs, what costs or benefits would accrue the platform if they were deprecated, and what is being communicated to developers when an API is deprecated. I explored this topic in my recent JavaOne talk, Debt and Deprecation. (Slides available at that link; video here.) It turns out that the JDK itself hasn't been very consistent in its usage of deprecation. It's been used to mean several different things, including for example,
This is dangerous and you should be aware of the risks of using it (example:Thread.stop()
, Thread.resume()
, and Thread.suspend()
).
This is going to be removed in a future release
This is obsolete and it's a good idea for you to use something different (example: many of the methods in java.util.Date
)
All of these are distinct meanings, and different subsets of them apply to different things that are deprecated. And some subset of them apply to things that aren't deprecated (but that maybe should be deprecated).
Cloneable
and Object.clone()
are "broken" in the sense that they have design flaws and are difficult to use correctly. However, clone()
is still the best way to copy arrays, and cloning has some limited usefulness to make copies of instances of classes that are carefully implemented. Removing cloning would be an incompatible change that would break a lot of things. A cloning operation could be reimplemented a different way, but it would probably be slower than Object.clone()
.
However, for most things a copy constructor is preferable to cloning. So perhaps marking Cloneable
as "obsolete" or "superseded" or something similar would be appropriate. This would tell developers that they probably want to look elsewhere, but it would not signal that the cloning mechanism might be removed in a future release. Unfortunately, no such marker exists.
As things stand, "deprecation" seems to imply eventual removal -- despite the fact that a vanishingly small number of deprecated features have ever been removed -- and so deprecation doesn't seem warranted for the cloning mechanism. Perhaps in the future an alternative marking can be applied that directs developers to use alternative mechanisms instead.
UPDATE
I've added some additional history to the bug report. Frank Yellin, an early JVM implementor and co-author of the JVM specification, made some comments in response to the "lost in the mists of time" comment in the TRC recommendation quoted in the other answer. I've quoted the relevant portions here; the full message is in the bug report.
Cloneable has no methods for the same reason that Serializable doesn't. Cloneable indicates a property of the class, rather than specifically saying anything about the methods that the class supported.
Prior to reflection, we needed a native method to make a shallow copy of an Object. Hence Object.clone() was born. It was also clear that many classes would want to override this method, and that not every class would want to be cloned. Hence Cloneable was born to indicate the programmer's intention.
So, in short. The purpose of Cloneable was not to indicate that you had a public clone() method. It was to indicate that you were willing to be cloned using Object.clone(), and it was up to the implementation to decide whether or not to make clone() public.
Cloneable
has very deep penetration into the JDK and removing it would entail such massive changes that the damaage would outweigh the damage it is currently making. – KavanaghCloneable
?". I hope you also see that it's easy to fall on the "polemic" side here. – BlearCloneable
is widely known. – KavanaghCloneable
is not deprecated yet. – DrawlCloneable
is broken is not an opinion, it is a medical fact. – BlearCloneable
broken, it's broken beyond repair. Maybe that's got something to do with it. – Rianonclone
unless they add members that require deep cloning]. In retrospect, a better approach would have been for Java to include aCloneableBaseObject
which derived from Object and implemented aclone
member via "JVM magic", and suggest that types which should be cloneable should derive from that, but the horse has long since left the barn. – SalveObject
and implementedCloneable
would be deemed to instead inherit fromCloneableBaseObject
, which itself implementedCloneable
. Under such a scenario,Object.clone()
could simply throw an exception, while the override inCloneableBaseObject
would behave asObject.clone()
does now when in those cases where it may legitimately be used. Ideally, there would also be a slight change to the rules about checked exceptions... – SalveClonableBaseObject.Clone
would specify that it used to throw a clone-not-supported exception, such that code which calledclone
on an object derived fromCloneableBaseObject
would be allowed to catch the exception (even though it would never be thrown) but would not be required to do so. – SalveCloneable
in ways that would be difficult to mimic any other way. – Salveclone
facility, which is distinct from all the treacherous curves built into the cloning mechanism as a whole. A different mechanism, based on the same low-level object copying, but fixing stuff such asfinal
field mutation and the awkwardness of shoving the cloneability semantics into the type system would probably be achievable. – Kavanagh