implementing clone


J

Joris Bleys

I want to create a container (SetList) which is capable of containing all
possiblie elements, but I ran into some problems implementing clone(). I
believe it should be a deep cloner (causing me lots of headaches).

Snippet from Thinking in Java (controlling cloneability):

Support cloning conditionally. If your class holds handles to other
objects that might or might not be cloneable (an example of this is a
collection class), you can try to clone all of the objects that you have
handles to as part of your cloning, and if they throw exceptions just
pass them through. For example, consider a special sort of Vector that
tries to clone all the objects it holds. When you write such a Vector,
you donÿt know what sort of objects the client programmer might put
into your Vector, so you donÿt know whether they can be cloned.

Does anyone how someone can actually implement this ?

public SetList duplicate() {
SetList duplicateSetList = new SetList();
Iterator i = this.iterator();
while (i.hasNext()) {
Object o = i.next();
// downcast needed
duplicateSetList.add(o.clone());
}
return duplicateSetList;
}

Because Object.clone() is protected, a downcast is needed (which I believe
has to be quite dynamic).

Any ideas ?
 
Ad

Advertisements

B

Brian J. Sayatovic

IF something is to be cloneable, it must implement the CLoneable interface.
Thus, you should be able to do this:

if(o instanceof Cloneable) {
duplicateSetList.add( ((CLoneable)o).clone() );
}
else {
if(o != null) {
// ???
throw new ClassCastException("Object in SetList is not
cloneable: " + o.getClass().getName());
}
}

Regards,
Brian.
 
J

Joris Bleys

IF something is to be cloneable, it must implement the CLoneable
interface. Thus, you should be able to do this:

if(o instanceof Cloneable) {
duplicateSetList.add( ((CLoneable)o).clone() );

I've tried this before, and : no dice :-/. This is because the
Cloneable-interface is empty, so ((Clobeable)o).clone() ) refers directly
to Object.clone() which is protected.

Humblest Greetings,

Joris
 
P

Patrick Buchholz

Joris Bleys said:
I want to create a container (SetList) which is capable of containing all
possiblie elements, but I ran into some problems implementing clone(). I
believe it should be a deep cloner (causing me lots of headaches).

You need to deep copy all objects in the list. There is a chapter about
cloning in the book "Optimized Java programming", don't have it with me but
I'll have a look when i am back home.

regards,

Patrick
 
T

Tim Tyler

: I want to create a container (SetList) which is capable of containing all
: possiblie elements, but I ran into some problems implementing clone(). I
: believe it should be a deep cloner (causing me lots of headaches).

If you can make everything you're dealing with serializable -
you can simply use this:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io_ObjectInputStream;
import java.io_ObjectOutputStream;
import java.io.Serializable;
import java.util.zip.CRC32;
import java.util.zip.Checksum;

public class ObjectUtilities implements Cloneable, Serializable {
/**
* Deep clone an object
*
* To use this - use code such as:
*
* public Object clone() {
* return ObjectUtilities.clone(this);
* }
*
* @param object - object to be copied
* @return - a copy of the object
*/
public static Object clone(Object object) {
byte[] ba = serializeToByteArray(object);

try {
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
ObjectInputStream ois = new ObjectInputStream(bais);
object = ois.readObject();
ois.close();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

return object;
}

private static byte[] serializeToByteArray(Object object) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
oos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}

return baos.toByteArray();
}
}
 
J

Joris Bleys

: I want to create a container (SetList) which is capable of containing all
: possiblie elements, but I ran into some problems implementing clone(). I
: believe it should be a deep cloner (causing me lots of headaches).

If you can make everything you're dealing with serializable -
you can simply use this:

Thanks for this information, this is indeed a solution to the deep cloning
problem, but I think it's quite a dirty fix for this problem. It's not
really an implementation of what that book wrote, but it could have helped
me.

My current beliefs are that there is no cleaner fix for this problem than
implementing an own Interface.

But thanks !!!

Xerox rox
 
Ad

Advertisements

J

Joris Bleys

You need to deep copy all objects in the list. There is a chapter about
cloning in the book "Optimized Java programming", don't have it with me but
I'll have a look when i am back home.

regards,

Patrick

Thanks for putting your time in my problem.

Joris
 
B

Brian J. Sayatovic

Actually, after discussing a differnet problem with a friend today, he
pointed out that Cloneable is a permission-granting interface (i.e.
has no methods), so .clone() is not necessarily public for Cloneable
objects.

The second solution would be to use reflection (java.lang.reflect.*)
to find the .clone() method and see if its public, then invoke it
reflectively.

This is some (unverified) pseudo code...

try {
Method cloneMethod = o.getmethod("clone", new Class[0]);
if(cloneMethod.getModifiers() & Modifier.PUBLIC == Modifier.PUBLIC)
{
try {
Object cloned = cloneMethod.invoke(new Object[] { o } );
duplicateSetList.add(cloned);
}
catch(Throwable t) {
// Couldn't clone -- handle error as appropriate
}
}
}
catch(NoSuchMethodException e) {
// Do nothing -- object doesn't have clone
}

Regards,
Brian.
 
Ad

Advertisements

J

Joris Bleys

The second solution would be to use reflection (java.lang.reflect.*)
to find the .clone() method and see if its public, then invoke it
reflectively.

I had heard about a reflective way to do this, but I haven't thought about
like this. But this seems very likely the way to implement what the book
said.

Your help is very much appreciated !

Xerox rox
 

Top