Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4103477
Votes 3
Synopsis rfe: Need support for deep copying of Object
Category java:classes_lang
Reported Against 1.1.4 , 1.1.5
Release Fixed
State 11-Closed, duplicate of 4098033, request for enhancement
Priority: 5-Very Low
Related Bugs 4098033
Submit Date 12-JAN-1998
Description




Given a generic container class whose contents
are described in terms of Object:
class GenericValue
{
  Object value;
  ...
}

there is no way for this class to create a deep
copy of an instance because Object.clone() cannot
be invoked on value because of the protected
attribute on clone(). Why isn't the CloneNotSupportedException sufficient protection
and Object.clone public?


This little program demonstrates the problem I am having:
racs21:: tmp 46 > cat GenericArray.java

class Int
{
        int i;

        Int(int j)
        {
                i = j;
        }
        int getIntValue()
        {
                return i;
        }
        void setIntValue(int j)
        {
                i = j;
        }
        public String toString()
        {
                return "Int="+i;
        }
}

public class GenericArray
{
        Object[] array;
        public GenericArray(int n)
        {
                array = new Object[n];
        }
        public void insertElementAt(Object o, int n)
        {
                if( n >= array.length )
                        throw new ArrayIndexOutOfBoundsException();
                array[n] = o;
        }
        public Object elementAt(int n)
        {
                if( n >= array.length )
                        throw new ArrayIndexOutOfBoundsException();
                return array[n];
        }
        // Would like to make deep copy...?
        public GenericArray copy()
        {
                GenericArray copy = new GenericArray(array.length);
                for(int n = 0; n < array.length; n ++)
                        // copy.array[n] = array[n].clone(); this is not allowed
but should be
                        copy.array[n] = array[n];       // Can only make a
shallow copy
                return copy;
        }


        public static void main(String[] args)
        {
                Object[] numbers = {new Int(0), new Int(1), new Int(2), new
Int(3)};
                GenericArray array0 = new GenericArray(4);
                for(int n = 0; n < numbers.length; n ++)
                        array0.insertElementAt(numbers[n], n);
                // Should be able to make copy without affecting numbers[]
                GenericArray array1 = array0.copy();
                Int i = (Int) array1.elementAt(0);
                i.setIntValue(10);
                for(int n = 0; n < numbers.length; n ++)
                        System.out.println(n+", array1="+array1.elementAt(n)+",
numbers="+numbers[n]);
        }
}

racs21:: tmp 47 > java GenericArray
0, array1=Int=10, numbers=Int=10 // The i.setIntValue(10) changed numbers[0]
1, array1=Int=1, numbers=Int=1
2, array1=Int=2, numbers=Int=2
3, array1=Int=3, numbers=Int=3
racs21:: tmp 48 > 


Since I can't invoke clone() on a Object type, I cannot make an element
by element deep copy of the Object[] array. I should be able to use
the 'copy[n] = array[n].clone();' statement commented out above and
allow a class to reject this by throwing a CloneNotSupportedException.
Am I missing some obvious work around?


(Review ID: 22777)
======================================================================
Work Around




None that I can find.
======================================================================
Evaluation
    The sad fact of the matter is that Cloneable is broken, and always has been.  The Cloneable interface should have a public clone method in it.  This is a very annoying problem, and one for which there is no obvious fix.  I suspect that we'll have to address it at some point, but any solution will be somewhat disruptive.

  xxxxx@xxxxx   1998-03-08
Comments
  
  Include a link with my name & email   

Submitted On 23-FEB-1998
schaefera
I encounter a similar problem.
I tried to expand the clone() method in the class
Vector to copy an entire tree (because also a
vector could contain another vector). Then I could
not do it because the clone() method of the class
Object is protected.


Submitted On 13-NOV-1998
jonbarril
For what its worth and for when you get around to
fixing clone(), here is a recent exchange
concerning clone() not being public and some
of the issues (non-issues?) concerning it.
David Smiley wrote:
&gt; 
&gt; clone() is protected in java.lang.Object so that by default, an object
&gt; is not cloneable.  Anything otherwise would be a security hazard
Why is being able to publicly clone an object a security issue?  If a
class has a reference to another class, I don't think the first class
can do anything with the clone that it couldn't do with the original.
&gt; and my
&gt; result in un-intended behavior for objects that should never be cloned
&gt; in the first place.
The un-intended behavior is that an exception will be thrown, which is
fine and expected for an object that does not implement Cloneable.
&gt; If you make a class that should be cloneable,
&gt; overide it, make it public, and make your class implement the cloneable
&gt; interface.
Yes, of course a subclass can expose clone() as public but that is
missing the point.  My utility class is meant to work with any Object,
not just special objects that have my special clone stuff.  That is
the whole point of polymorphism.
&gt; You may need some special handling in clone() to properly
&gt; duplicate the data members.  By default, the internal clone() will NOT
&gt; &quot;deep clone&quot;, so you may have to call clone on your data members
&gt; yourself in your overrided clone().
Again, the idea is to let polymorphism do its job.  The idea is that
the utility class calls Object.clone() and via polymorphism the
subclass clone() is actually called, which presumably is capable of
performing the deep copy.  the problem is that unless Object.clone()
is public there is no way to do this unless I set up my own redundant
version of cloning.
--jon 
&gt; 
&gt; Cheers,
&gt;         David Smiley
&gt; 
&gt; jonb@sirius.com wrote:
&gt; &gt;
&gt; &gt; Did you ever receive an answer to this?  I was kind of wondering the
same
&gt; &gt; thing, as well as why clone() is protected instead of public.  It
seems like
&gt; &gt; cloning is something that would be generally useful for any class to
do, not
&gt; &gt; just subclasses or package-mates.
&gt; &gt;
&gt; &gt; The problem I ran into was in developing a utility class to clone a
data
&gt; &gt; object and &quot;pass&quot; it from one object to another along a
special route.  The
&gt; &gt; source and sink objects are friends of the data object class but the
utility
&gt; &gt; that passes it is not, intentionally to keep it generic.  Since
clone() is
&gt; &gt; protected the utility can't call it, forcing me to abandon the scheme
or to
&gt; &gt; develop my own public cloning scheme, which seems awfully redundant.
&gt; &gt; Comments?
&gt; &gt;
&gt; &gt; --jon
&gt; &gt;
____________________ Peculiar Technologies ____________________
Jon Barrilleaux       3800 Lake Shore Ave.         Purveyors of
jonb@sirius.com        Oakland, CA 94610      Alternate Reality
510.444.4370 voc                           Augmented Simulation
510.444.0231 fax        www.augsim.com         and 3D Solutions



PLEASE NOTE: JDK6 is formerly known as Project Mustang