为什么 java clone() 留下同一个对象

why java clone() left same object

第一部分是:

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");
        ... ...
    }}

火车是:

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;
    }
}

据我所知,可能是构造函数引起的一些问题。 我在控制台中得到的是:

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

我看了一些如何克隆对象的指南,据我所知,我的克隆方法是一样的

如果我们想要创建对象 X 的深层副本并将其放置在新对象 Y 中,则会创建任何引用对象字段的新副本,并将这些引用放置在对象 Y 中。这意味着在引用中所做的任何更改对象 X 或 Y 中的对象字段将仅反映在该对象中,而不会反映在另一个对象中。在下面的示例中,我们创建了对象的深拷贝。 深拷贝复制所有字段,并制作字段指向的动态分配内存的副本。当一个对象与其引用的对象一起被复制时,就会发生深拷贝。

// 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); 
    } 
} 

我刚刚使用 Serializable 工具解决了这个问题:

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();

我的老师说它会起作用,但这不是最好的方法,尤其是在大型项目中。

或者可以这样做:

@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;
    }