|
Quick Lists
|
|
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
|
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:
>
> clone() is protected in java.lang.Object so that by default, an object
> 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.
> and my
> result in un-intended behavior for objects that should never be cloned
> 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.
> If you make a class that should be cloneable,
> overide it, make it public, and make your class implement the cloneable
> 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.
> You may need some special handling in clone() to properly
> duplicate the data members. By default, the internal clone() will NOT
> "deep clone", so you may have to call clone on your data members
> 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
>
> Cheers,
> David Smiley
>
> jonb@sirius.com wrote:
> >
> > Did you ever receive an answer to this? I was kind of wondering the
same
> > thing, as well as why clone() is protected instead of public. It
seems like
> > cloning is something that would be generally useful for any class to
do, not
> > just subclasses or package-mates.
> >
> > The problem I ran into was in developing a utility class to clone a
data
> > object and "pass" it from one object to another along a
special route. The
> > source and sink objects are friends of the data object class but the
utility
> > that passes it is not, intentionally to keep it generic. Since
clone() is
> > protected the utility can't call it, forcing me to abandon the scheme
or to
> > develop my own public cloning scheme, which seems awfully redundant.
> > Comments?
> >
> > --jon
> >
____________________ 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
|
|
|
 |