Nikita Shadkov
Nikita Shadkov

Reputation: 660

why java clone() left same object

First part is:

public class Lab2 {
   public static void main(String[]args) throws Exception {
        Train train1 = new Train(3);
        Train train1Copy = train1.clone();
        train1Copy.carriages[0][0] = 5125;

        System.out.println("train1")
        System.out.println("Copyed");
        ... ...
    }}

Train is:

public class Train implements Cloneable {
    private int petrol, bananas, coal, grains, fertilizers;
    // количество вагонов, и груз в них
    int[][] carriages;

    public Train(int numOfCarriages) {
        carriages = new int[numOfCarriages][5];
        for (int i=0; i<numOfCarriages; i++) {
            petrol = (int)Math.round(Math.random() * 13);
            ... ...
            carriages[i][0] = petrol;
            ... ...
        }
    }

    @Override
    public Train clone() throws CloneNotSupportedException {
        return (Train) super.clone();
    }
    public String getPetrol() {
        String petrolText = "";
        for (int i=0; i<carriages.length; i++) {
             petrolText += i+1 + " carriage petrol= " + carriages[i][0] + "\n";
        }
        return petrolText;
    }
}

As I think, there could be some problems caused by constructor. And what I got in console is:

train1
1 carriage petrol= 5125
2 carriage petrol= 1
3 carriage petrol= 8


Copyed
1 carriage petrol= 5125
2 carriage petrol= 1
3 carriage petrol= 8

I watched some guides how to clone objects and as I see, my clone method is the same

Upvotes: 0

Views: 123

Answers (3)

Nikita Shadkov
Nikita Shadkov

Reputation: 660

Or it could be done this way:

@Override
    public Train clone() throws CloneNotSupportedException {
        Train train = (Train) super.clone();
        train.carriages = new int[carriages.length][5];
        for (int i=0;i<carriages.length;i++){
            for (int y=0; y<5; y++){
                train.carriages[i][y] = carriages[i][y];
            }
        }
        return train;
    }

Upvotes: 0

Nikita Shadkov
Nikita Shadkov

Reputation: 660

I just solved it with using Serializable implement:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream ous = new ObjectOutputStream(baos);
        ous.writeObject(train1);
        ous.close();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);

        Train train1Copy = (Train) ois.readObject();

My teacher said it will work, but it's not the best way to do it especially in big projects.

Upvotes: 0

SandOfTime
SandOfTime

Reputation: 814

If we want to create a deep copy of object X and place it in a new object Y then new copy of any referenced objects fields are created and these references are placed in object Y. This means any changes made in referenced object fields in object X or Y will be reflected only in that object and not in the other. In below example, we create a deep copy of object. A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

// A Java program to demonstrate deep copy 
// using clone() 
import java.util.ArrayList; 

// An object reference of this class is 
// contained by Test2 
class Test 
{ 
    int x, y; 
} 


// Contains a reference of Test and implements 
// clone with deep copy. 
class Test2 implements Cloneable 
{ 
    int a, b; 

    Test c = new Test(); 

    public Object clone() throws
                CloneNotSupportedException 
    { 
        // Assign the shallow copy to new reference variable t 
        Test2 t = (Test2)super.clone(); 

        t.c = new Test(); 

        // Create a new object for the field c 
        // and assign it to shallow copy obtained, 
        // to make it a deep copy 
        return t; 
    } 
} 

public class Main 
{ 
    public static void main(String args[]) throws
                            CloneNotSupportedException 
    { 
    Test2 t1 = new Test2(); 
    t1.a = 10; 
    t1.b = 20; 
    t1.c.x = 30; 
    t1.c.y = 40; 

    Test2 t3 = (Test2)t1.clone(); 
    t3.a = 100; 

    // Change in primitive type of t2 will not 
    // be reflected in t1 field 
    t3.c.x = 300; 

    // Change in object type field of t2 will not 
    // be reflected in t1(deep copy) 
    System.out.println(t1.a + " " + t1.b + " " + 
                        t1.c.x + " " + t1.c.y); 
    System.out.println(t3.a + " " + t3.b + " " + 
                        t3.c.x + " " + t3.c.y); 
    } 
} 

Upvotes: 1

Related Questions