2

Possible Duplicate:
How do I copy an object in Java?

How can I initialize an object (say A) in java and set its initial member values equal to a second object (say B). After initialization I want to modify the members of A without modifying the members of B. So at initialization of A I only want to copy the data of B. How is this done in a nice way??

Community
  • 1
  • 1
sjoerd999
  • 139
  • 2
  • 12

4 Answers4

1

You could implement and use clone

MyClass b = new MyClass();
MyClass a = b.clone();

Note: some classes are not Cloneable, or have broken implementations. e.g. only have a shallow copy when they should be a deep copy.

If the class is Serializable you can serialize it and deserialize it in memory. Not exactly nice but it works.

Or you could create your own "copy" constructor.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

Cloning is a straightforward option for copying. If you ever want to do something where you need more control, create your own method that performs your copy exactly how you need it:

public MyType copy()
{
  MyType a = new MyType();
  // Initialize how you need to here, use the object this was called from if you'd like
  a.property = this.property;
  // etc.  
  return a;
}

This gives you more direct control, but takes more time to code. If clone will suit your purposes, stick to that.

EDIT: I am going to give an example based on your comments on this answer.

Let us assume we have the following types:

TypeA: has the following member variables
int number = 5; // Default value built in by constructor.
int letter = 'x'; // Value is 'a' when constructed but has been changed.
ArrayList<TypeB> list = {b1, b2, b3} // All are initialized.

TypeB: has the following member variables
double decimal = 5.32
TypeC someObject = ...

TypeC: has some stuff, but we are going to ignore it.

Now, When we want to copy TypeA, we must do the following:

  1. Copy over the number and character directly as they are value types.
  2. Copy over a reference to the ArrayList which contains a reference to some TypeBs.

Luckily those are easy steps.

int copyNumber = this.number;
char copyChar = this.letter;
ArrayList<TypeB> copyList = this.list;
return new TypeA(copyNumber, copyChar, copyList);

Now that assumes a particular constructor that takes those three arguments, but hopefully you get the idea.

It would get tricky if you wanted to just get values, not references to all of the TypeBs in the ArrayList. You would have to loop through the ArrayList and create new TypeBs that copied all of ITS values (double and TypeC objects as either references or values...)

In short, what you want is an easier copy to perform. Simple assignment operators copy values with primitive types and references with Objects.

BlackVegetable
  • 12,594
  • 8
  • 50
  • 82
  • Ok but if the object I want to copy contains other objects as methods? – sjoerd999 Jun 28 '12 at 20:21
  • @sjoerd999: What is the issue you are having? I can probably help you. – BlackVegetable Jun 28 '12 at 20:21
  • Ok, I'll try to explain: I have an object A, it has other objects as members. And also has datastructures as members (arrays, lists etc...). So an copy constructor will be a little hard because as I understood you have to copy everything at the level of primitive data types. Cloning will not work either because of the same reasons. So what to do? Or am I making this seemingly easy problem too hard now? – sjoerd999 Jun 28 '12 at 20:26
  • Ah, so the question becomes a bit more tricky. Do you want to copy *references* to these other objects? Or are you only interested in the *values* these objects represent? – BlackVegetable Jun 28 '12 at 20:27
  • I want to copy all the values of the primitive data types and the arrays and lists. And I want to copy the references to the objects which are member of object A. – sjoerd999 Jun 28 '12 at 21:54
0

One possible solution for that would be implement clone method on your class and use clone as follows:

MyClass a = new MyClass();
MyClass b = a;

You will notice that clone() isn't really a public method, so your will need to expose it. Additionally you need to tell Java that your object is Cloneable (this is done making your class implement Cloneable). The following code ilustrate it:

public class MyClass implements Cloneable {

    @Override
    protected MyClass clone() throws CloneNotSupportedException {
        return (MyClass)super.clone();
    }

}
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
0

That all depends on the type of the members. I'll give an Example:

class A
{
    public float value;
    public int[] anArray;

    public A(B b)
    {
        //primitive may be assigned directly.
        this.value = b.value;

        // other types different approaches:

        //copy the contents of the array
        this.anArray = new int[b.anArray.length];
        System.arraycopy(b.anArray, 0, this.anArray, 0, b.anArray.length);
    }
}

class B
{
    float value;
    int[] anArray;
    public B(int size)
    {
        this.value = 3f;
        this.anArray = new int[size];
        for (int i = size - 1; i >= 0; i--)
        {
            this.anArray[i] = i * 10;
        }
    }
}

B b = new B(5);
A a = new A(b);
Moji
  • 11
  • 2