Java 在内存中复制整个对象

Java 在内存中复制整个对象,java,Java,我有这个: import java.util.ArrayList; public class MyClass { ArrayList list = new ArrayList(); public MyClass(){ } public MyClass(MyClass aClass){ this.list = aClass.getList(); } public void add(int number){

我有这个:

import java.util.ArrayList;


public class MyClass {
    ArrayList list = new ArrayList();

    public MyClass(){

    }

    public MyClass(MyClass aClass){
        this.list = aClass.getList();
    }

    public void add(int number){
        list.add(number);
    }

    public void set(int number){
        list.set(0, number);
    }

    public int get(){
        return (Integer)list.get(0);
    }

    public ArrayList getList(){
        return list;
    }
}



MyClass aName = new MyClass();
aName.add(5);
System.out.println("aName: "+aName.get());

MyClass aName2 = new MyClass(aName);
System.out.println("aName2: "+aName2.get());

aName2.set(1);
System.out.println("aName2: "+aName2.get());
System.out.println("aName: "+aName.get());
这将打印: 阿纳姆:5 阿纳梅2:5 阿纳梅2:1 阿纳姆:1

我不希望第二个对象更改第一个对象中的值。
有没有办法阻止这种情况的发生,但仍然能够从另一个对象复制属性?

然后不要将列表从原始对象传递到新对象,在

public MyClass(MyClass aClass){ 
    this.list = aClass.getList(); 
} 
它使两个对象都有一个对同一列表的引用(两个对象之间只共享一个列表)

你应该这样做

public MyClass(MyClass aClass){ 
    this.list = (List) aClass.getList().clone(); 
} 

然后,不要将列表从原始对象传递到新对象

public MyClass(MyClass aClass){ 
    this.list = aClass.getList(); 
} 
它使两个对象都有一个对同一列表的引用(两个对象之间只共享一个列表)

你应该这样做

public MyClass(MyClass aClass){ 
    this.list = (List) aClass.getList().clone(); 
} 

是的,你可以阻止这一切。您需要在副本构造函数中创建列表的防御性副本

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}

您可以使用
clone()
,但正如Josh Bloch在有效的Java项目“复制构造函数比
clone
有许多优势”中所说的那样,它们在实践中更可取。

是的,您可以停止这种做法。您需要在副本构造函数中创建列表的防御性副本

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}
您可以使用
clone()
,但正如Josh Bloch在有效的Java项目“复制构造函数比
clone
”中所说的那样,它们在实践中更可取。

您可以克隆()或复制,但既然您已经创建了一个列表,而不是放弃它,您就可以使用它。

您可以克隆()或复制,但由于您已经创建了一个列表,您可以使用它,而不是放弃它。;)

您正在将
ArrayList
的参考值复制到新对象中。您现在有两个对同一列表的引用

构造第二个对象时,需要创建新的
ArrayList

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}
但是,请注意,两个列表现在包含相同的对象。同样,这只会创建一个新列表,并复制原始列表中对象的参考值。如果需要包含唯一对象的两个完整且独立的列表,则需要编写一个进行深度复制的方法,同时复制列表中的对象

您正在将
ArrayList
的参考值复制到新对象中。您现在有两个对同一列表的引用

构造第二个对象时,需要创建新的
ArrayList

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}

但是,请注意,两个列表现在包含相同的对象。同样,这只会创建一个新列表,并复制原始列表中对象的参考值。如果需要包含唯一对象的两个完整且独立的列表,则需要编写一个进行深度复制的方法,同时复制列表中的对象

您需要复制内部ArrayList,而不仅仅是分配引用。e、 g.
this.list=aClass.getList().clone()
你到底为什么要返回你自己的arraylist?@wug他不是,这是围绕数组列表创建行为。嗯,你说得对。他在和一个arraylist打交道。插入到arraylist开头是否在O(N)时间内运行?您需要复制内部arraylist,而不仅仅是分配引用。e、 g.
this.list=aClass.getList().clone()
你到底为什么要返回你自己的arraylist?@wug他不是,这是围绕数组列表创建行为。嗯,你说得对。他在和一个arraylist打交道。插入arraylist的开头是否在O(N)时间内有效?检查是否有必要强制转换,因为clone()返回对象。检查是否有必要强制转换,因为clone()返回对象。没错,他正在声明时创建一个。
final
变量之所以有用的另一个原因是,它会在编译时检测到这个bug!这是真的,他正在创造一个宣言。
final
变量之所以有用的另一个原因是,它会在编译时检测到这个bug!