Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #35473 > unrolled thread

What's the best way to clone a generic object?

Started byEric Douglas <e.d.programmer@gmail.com>
First post2016-08-26 11:56 -0700
Last post2016-08-27 07:47 +0200
Articles 2 — 2 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  What's the best way to clone a generic object? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 11:56 -0700
    Re: What's the best way to clone a generic object? Marcel Mueller <news.5.maazl@spamgourmet.org> - 2016-08-27 07:47 +0200

#35473 — What's the best way to clone a generic object?

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-26 11:56 -0700
SubjectWhat's the best way to clone a generic object?
Message-ID<3bfbd6f7-8b66-4733-9d52-68f498ee84ba@googlegroups.com>
For example:

public class MainClass<T extends MyGeneric> {
   private T copyFrom;
   private T copyTo;
   public void copyIt() {
      // code here to turn copyTo into a deep copy of copyFrom
   }
}

public abstract class MyGeneric {
   
}

public class OneExample extends MyGeneric {
   private String s;
   private int i;
}

public class AnotherExample extends MyGeneric {
   private String s;
   private byte[] b;
}

I searched the web and they generally said don't use Cloneable.

Here are some of the answers.
1) Require a method in every extended class that would create a new instance of itself and manually copy every member.  Since my base class is abstract this could be an abstract method, otherwise could require an interface (does that even force subclasses to implement?).

2) Add the deepClone dependency. https://github.com/kostaskougios/cloning

3) Serialize.  which simply means copyTo = serialize(copyFrom) as follows

     public static <T> T serialize(final T testObject) {

          final ByteArrayOutputStream out = new ByteArrayOutputStream();
          T endTestObject;
          try {
               final ObjectOutputStream oos = new ObjectOutputStream(out);
               oos.writeObject(testObject);
               oos.close();

               // deserialize
               final byte[] streamingBytes = out.toByteArray();
               final ByteArrayInputStream in = new ByteArrayInputStream(streamingBytes);
               final ObjectInputStream ois = new ObjectInputStream(in);

               endTestObject = (T) ois.readObject();
               endTestObject.getClass();
          } catch (final Exception e) {
               return null;
          }
          return endTestObject;
     }

[toc] | [next] | [standalone]


#35481

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2016-08-27 07:47 +0200
Message-ID<npr9h5$ghd$1@gwaiyur.mb-net.net>
In reply to#35473
On 26.08.16 20.56, Eric Douglas wrote:
> For example:
>
> public class MainClass<T extends MyGeneric> {
>     private T copyFrom;
>     private T copyTo;
>     public void copyIt() {
>        // code here to turn copyTo into a deep copy of copyFrom
>     }
> }

[...]

> I searched the web and they generally said don't use Cloneable.

Well, if you really need clone semantics, you may use Clonable, of 
course. It is at least better than just overriding Object.clone().
But in Java and other reference based languages there very few use cases 
where clone is the best solution. So maybe the hint is not to abuse the 
clone pattern.

The semantic of clone is always context dependent. Sometimes you need a 
shallow copy sometimes you need a deep copy, sometimes something in 
between. Neither Object.clone nor Clonable reflects this differences.


> Here are some of the answers.
> 1) Require a method in every extended class that would create a new instance of itself and manually copy every member.  Since my base class is abstract this could be an abstract method, otherwise could require an interface (does that even force subclasses to implement?).

The latter is the question about deep clone.

> 2) Add the deepClone dependency. https://github.com/kostaskougios/cloning

Never heard about that. But it sounds like a really dirty hack with 
reflections to get some design time convenience.
Well, if you intend to write an ORM or another similar complex class 
library it might be appropriate.

> 3) Serialize.  which simply means copyTo = serialize(copyFrom) as follows

This is one of the solutions with least performance - steamroller tactics.
The conversion into the intermediate binary format is entirely 
superfluous. The only benefit is the usually easy to use serialization 
framework.

But this method will also duplicate any immutable class like String, 
where clone is normally a no-op because there are absolutely no benefits 
of doing this. The drawback of this might be a considerably increased 
memory footprint and working set, including secondary impacts like 
decreased cache efficiency. In fact a pattern in modern application 
design is the opposite: deduplication. This is a concept behind in 
memory data bases and can give really impressive performance boosts in 
some cases. (BTDT, gain ~2 orders of magnitude).


Marcel

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web