Re: A better cloning mechanism (was: Why not cloneable by default?)

From: Tony Morris (not_at_telling.you)
Date: 03/22/05


Date: Wed, 23 Mar 2005 07:13:49 +1000


"John C. Bollinger" <jobollin@indiana.edu> wrote in message
news:d1p9e8$cpt$1@rainier.uits.indiana.edu...
> CLJA removed as not relevant to this branch of the discussion.
>
> Thomas G. Marshall wrote:
>
> > Does anyone know why the java designers didn't make every object
> > shallow-cloneable by default?
> >
> > I understand the implications of cloning something overly hefty, and to
be
> > cautious about such things, but it still seems a little overboard to me
to
> > err on the side of turning if off.
> >
> > Turning it off could easily have been accomplished by implementing
something
> > called:
> >
> > public interface NotCloneable {}
> >
> > In fact, I might have allowed two methods, deep within Object:
> >
> > public Object shallowClone()
> >
> > and
> >
> > public Object deepClone()
> >
> > Now deep cloning is of course fraught with peril, and I am normally very
> > much in favor of the safety restrictions in the java language, but I'm
not
> > sure this is the kind of thing that java should protect against.
>
> So as long as we're having this discussion, perhaps we can come up with
> a real design for a better Java cloning mechanism. (Then we just have
> to build a time machine, and this whole thread will vanish :-).) I
> think, for those who are game, that we should start right at the
> beginning, by defining the requirements and specifications. The
> following are my own restatement of what I think are the key specs
> behind Java's existing mechanism:
>
> General Requirements
>
> 1) The cloning mechanism shall produce from an object a distinct object
> of the same class that is logically a copy of the original.
>
> 2) The definition of "logically a copy" shall be controllable by
> individual classes.
>
> 3) Classes shall be able to control whether or not their instances may
> be cloned.
>
> Specifics
>
> 4) A default cloning implementation shall be provided that performs a
> field-by-field (shallow) copy of an object's state to initialize the
clone.
>
>
> Before we go on, then, the floor is open for discussion of the specs.
>
>
> --
> John Bollinger
> jobollin@indiana.edu

I'm not sure if this is what you were meaning to say, but the only real
contract for implementers is specified by Object.clone().
To paraphrase the important parts:

x.clone() != x
x.clone().getClass() == x.getClass();
"typically the case, but not an absolute requirement":
x.clone().equals(x)
"By convention, the returned object should be obtained by calling
super.clone [sic super.clone()]
"By convention, the object returned by this method should be independent of
this object..."
etc.

How should we fix it? Here's one easy way:

package com.fixbrokenapis;
public interface Cloneable<T>{T clone();}

The same could be said for the equals/hashCode methods being better off
extracted to an interface - the consequences being less dire, but in my
opinion, still an atrocity as it currently (and always will) stands. A
practical example is the answer to the question, "how many times have you
seen a broken implementation?" I don't know about you, but I see it broken
more times than not.
...and if you are a "Nazi" (to quote my work colleagues), you would *always*
use an interface, *never* declare a class non-final, *never* expose
constructors (declared private), *never* expose the ability to mutate an
object through the interface, and always follow the TDD process
(encapsulation is paramount!). Of course, sometimes Nazis have to violate
their own rules - typically, it's to fit into some other framework that
mandates it.
It's just a matter of "where do *you* draw the line?". I argue that if you
don't draw the line at the level of a perceived "Nazi" (or somewhere
thereabouts), then you merely have more learning to do on the subject - not
to suggest that I too, don't indulge in the process of learning.
The existing clone mechanism is down the severe end of being broken, so
someone who is not a "Nazi" might consider reimplementing it.
</rant>

-- 
Tony Morris
http://xdweb.net/~dibblego/


Relevant Pages

  • A better cloning mechanism (was: Why not cloneable by default?)
    ... > I understand the implications of cloning something overly hefty, ... > sure this is the kind of thing that java should protect against. ... The cloning mechanism shall produce from an object a distinct object ... field-by-field (shallow) copy of an object's state to initialize the clone. ...
    (comp.lang.java.programmer)
  • HEADSUP: Network interface cloning changes
    ... I just commited network interface cloning. ... named stf rather then stf0 and ifconfig will not print "stf0" to stdout. ... to understand example of the new cloning code then that provided by ...
    (freebsd-current)
  • Re: [patch for review] Fwd: CURRENT: ifconfig tap0 results in core dump
    ... cloning instead of devfs cloning which would fix some of this, ... >> How soon after killing openvpn, do you use the ifconfig command. ... > enumerates off the tap interface, ...
    (freebsd-net)
  • Re: Why not cloneable by default?
    ... > I understand the implications of cloning something overly hefty, ... > much in favor of the safety restrictions in the java language, ... its correct the Object class implement clone() does nothing ...
    (comp.lang.java.programmer)
  • Re: Why not cloneable by default?
    ... > I understand the implications of cloning something overly hefty, ... > Now deep cloning is of course fraught with peril, ... > much in favor of the safety restrictions in the java language, ...
    (comp.lang.java.programmer)