lexicore lexicore - 4 days ago 4
Java Question

Modern day alternatives to Cloneable?

It is well-known that

Cloneable
is broken beyond repair (see the discussion in this question for more information).

Last questions on alternatives and "how do I do it right" are few years old:



So I'd like to ask again:

What are the modern day (2014) alternatives to
Cloneable
?


I am looking for a general-purpose solution. I could imagine the following requirements:


  • Some kind of
    Copyable
    interface which the classes will implement:
    A extends Copyable
    .

  • Deep copying. If an istance of
    A
    references an instance of
    B
    ,
    a.copy()
    should reference a new
    b.copy()
    .

  • Copy to the specified target:
    a.copyTo(a1)
    .

  • Polymorphic copying: if
    B
    extends
    A
    then
    a.copyTo(b)
    should copy all the properties of
    B
    from
    a
    to
    b
    .



Of course I can implement all of this by myself, but wouldn't it be reasonable to have standard interfaces for this? Or am I missing something?




A bit of the background for my context. I'm working a lot with JAXB and schema-derived classes. It is often extremely useful to have deep copying for these classes. Few years ago I wrote a couple of JAXB schema compiler plugins to generate
copyTo
methods which implement the requirements above (and more). I had to use my own runtime API. Now I was revisiting the case and decided to ask if there's a standard solution.

Answer

First of all, I disagree with people saying that Cloneable is "broken". It is not "broken" -- it does exactly what it is documented to do, which is to cause Object.clone() to throw an exception or not. People don't like it because they assume it is something it isn't -- they assume that it is an interface for objects that can be cloned, which was never what it was supposed to be for.

Java (still) does not have an interface in the standard library for objects that can be cloned. It would be nice if they added such an interface, but they haven't. You could make your own interface, and you can make your own classes implement it, but the problem is that you cannot make existing standard library classes implement it. So that would only be useful if you were only dealing with an ecosystem of your own classes.