为什么 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;
}
第一部分是:
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;
}