4

I want to create a list/array of object with the same parent class which then I will use it for reference. but i dont know how to clone those object to make a new object.

here is the example

BigFoo a;
SmallFoo b;
ChickenFoo c;
List<Foo> foos;
foos.add(a);
foos.add(b);
foos.add(c);

Foo foo = foos.get(1).clone();

but in Java i found no clone function in the default function. I wonder how this is accomplished?

Fugogugo
  • 4,460
  • 10
  • 36
  • 50

2 Answers2

4

The general suggestion: use a copy constructor. In fact, only a class itself knows how to create a clone of itself. No class can clone an instance of another class. The idea goes like this:

public class Foo {
  public List<Bar> bars = new ArrayList<Bar>();
  private String secret;

  // Copy constructor
  public Foo(Foo that) {
    // new List
    this.bars = new ArrayList<Bar>();

    // add a clone of each bar (as an example, if you need "deep cloning")
    for (Bar bar:that.bars) {
      this.bars.add(new Bar(bar));
    }

    // clone the secret value
    this.secret = new String(that.secret);
  }

  // ...

}

So if we want to clone a foo, we simply create a new one based on foo:

Foo clonedFoo = new Foo(foo);

That's the recommended way to clone an instance.


copy constructor works well with inheritance. Consider a subclass

 public ChildFoo extends Foo {

   private int key;

   public ChildFoo(ChildFoo that) {
     super(that);
     this.key = that.key;
   }
 }

Foo has a copy constructor and ChildFoo simply calls it from it's own copy constructor.

Your example is possible but not advisable. What will happen:

 Foo a = new Foo();
 ChildFoo b = new ChildFoo(a);  

This would require a constructor on ChildFoo like:

 public ChildFoo(Foo that) {
     // call the copy constructor of Foo -> no problem
     super(that);

     // but how to initialize this.key? A Foo instance has no key value!
     // Maybe use a default value?
     this.key = 0;
 }

Technically not a challenge but b is not a clone of a because the objects don't have the same type. So this (your example) is not cloning.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • that will work for the same class object. but how about its inherited class? Foo a = new Foo(); ChildFoo child = new ChildFoo(a); can this work? – Fugogugo Feb 21 '11 at 13:46
  • Copy constructor only works if you know the exact type of the object being copied. If you need to clone a `List`, which class constructor are going to use (ArrayList, LinkedLink, etc)? – Steve Kuo Jul 29 '12 at 16:36
  • @Steve - The `List` interface does not have a *clone* method, so how would you do that? We can't clone *interfaces*. – Andreas Dolk Jul 29 '12 at 19:20
1

One easy way would be to use a json mapper (Jackson or Gson) and write out the object as a string and then creating the clone object by using the string.

dhan
  • 63
  • 1
  • 4