为什么用“复制”在java中复制列表是错误的&引用;?

为什么用“复制”在java中复制列表是错误的&引用;?,java,list,Java,List,我试图通过以下方式从A构建列表B: List<Integer> B = A; B.addAll(A); B.add(new_element); 以前没有问题 有人知道原因吗?非常感谢。这样,您只需复制参考资料 如果您执行了A.add(“Test”),则B中也将包含“Test” 因此,如果在Java程序的另一部分中使用B,并删除“Test”,它也将从A中删除。但是您会认为B只是修改过的,因此您将有逻辑问题或难以调试的副作用。这样,您只需要复制引用 如果您执行了A.add(“Test

我试图通过以下方式从A构建列表B:

List<Integer> B = A;
B.addAll(A);
B.add(new_element);
以前没有问题


有人知道原因吗?非常感谢。

这样,您只需复制参考资料

如果您执行了
A.add(“Test”)
,则
B
中也将包含
“Test”


因此,如果在Java程序的另一部分中使用
B
,并删除
“Test”
,它也将从
A
中删除。但是您会认为
B
只是修改过的,因此您将有逻辑问题或难以调试的副作用。

这样,您只需要复制引用

如果您执行了
A.add(“Test”)
,则
B
中也将包含
“Test”

因此,如果在Java程序的另一部分中使用
B
,并删除
“Test”
,它也将从
A
中删除。但是你会认为
B
只是被修改过的,所以你会有逻辑问题或者很难调试的副作用。

使用
=
不会复制,它只会将两个变量指向同一个对象

使用一个经典示例,如果您有一个类

class Foo {
  private List<Object> bar;

  constructor(List<Object> start) {
    bar = start;
  }

  getBar() {
    return this.bar;
  }
}
class-Foo{
私人列表栏;
构造函数(列表开始){
bar=开始;
}
getBar(){
返回此.bar;
}
}
如果您运行:

List<Object> bar1 = new LinkedList<Object>();
Foo foo = new Foo(bar1);
bar1.getBar().add(new Object());
listbar1=newlinkedlist();
Foo-Foo=新的Foo(bar1);
bar1.getBar().add(新对象());
您希望
foo.getBar()
的长度是多少

因为您只是传递对列表的引用,而不是复制,所以
bar1.add
调用实际上会将一个项目添加到
foo
的内部
bar
。它们不是单独的列表,您刚刚告诉
foo
挂起对
bar1
的引用,它会这样做

这意味着对列表的任何更改都将影响可能包含引用的任何其他对象,当您使用多线程代码或向某人传递您希望他们不会更改的数据时,这可能是致命的。

使用
=
不会复制,它只会将两个变量指向同一对象

使用一个经典示例,如果您有一个类

class Foo {
  private List<Object> bar;

  constructor(List<Object> start) {
    bar = start;
  }

  getBar() {
    return this.bar;
  }
}
class-Foo{
私人列表栏;
构造函数(列表开始){
bar=开始;
}
getBar(){
返回此.bar;
}
}
如果您运行:

List<Object> bar1 = new LinkedList<Object>();
Foo foo = new Foo(bar1);
bar1.getBar().add(new Object());
listbar1=newlinkedlist();
Foo-Foo=新的Foo(bar1);
bar1.getBar().add(新对象());
您希望
foo.getBar()
的长度是多少

因为您只是传递对列表的引用,而不是复制,所以
bar1.add
调用实际上会将一个项目添加到
foo
的内部
bar
。它们不是单独的列表,您刚刚告诉
foo
挂起对
bar1
的引用,它会这样做


这意味着对列表的任何更改都将影响可能包含引用的任何其他对象,当您使用多线程代码或向某人传递您希望他们不会更改的数据时,这可能是致命的。

因此,当您使用“=”时,您只需复制主对象的引用即可。因此,如果主对象中有任何更改,那么它们也将反映在另一个对象中

但是,当您使用列表的addAll()方法时,此函数将删除对主对象的所有引用,如果使用简单的add()方法,则不会删除引用。因此,在使用add()添加列表后,如果添加的列表中有任何更改,那么它们也将反映在主列表中。让我们以下面的例子为例:

List<Object> l = new ArrayList<Object>();
List<Object> l1 = new ArrayList<Object>();
l1.add("Abhishek");

List<Object> l2 = new ArrayList<Object>();
l2.add("Vishvendra");

l.addAll(l1);
l.add(l2);

System.out.println(l.toString()); //this will print [Abhishek, [Vishvendra]]        

l1.add("Rushikesh");
l2.add("Talina");

System.out.println(l.toString()); //now this will print [Abhishek, [Vishvendra, Talina]]
listl=newarraylist();
列表l1=新的ArrayList();
l1.添加(“阿披实”);
列表l2=新的ArrayList();
l2.添加(“Vishvendra”);
l、 addAll(l1);
l、 添加(l2);
System.out.println(l.toString())//这将印刷[阿披舍克[维什文德拉]]
l1.添加(“Rushikesh”);
l2.添加(“塔利纳”);
System.out.println(l.toString())//现在这将印刷[阿披舍克,[维什文德拉,塔利纳]]
我想现在很容易理解了。
检查addAll()方法的行为。

因此,当使用“=”时,只需复制主对象的引用即可。因此,如果主对象中有任何更改,那么它们也将反映在另一个对象中

但是,当您使用列表的addAll()方法时,此函数将删除对主对象的所有引用,如果使用简单的add()方法,则不会删除引用。因此,在使用add()添加列表后,如果添加的列表中有任何更改,那么它们也将反映在主列表中。让我们以下面的例子为例:

List<Object> l = new ArrayList<Object>();
List<Object> l1 = new ArrayList<Object>();
l1.add("Abhishek");

List<Object> l2 = new ArrayList<Object>();
l2.add("Vishvendra");

l.addAll(l1);
l.add(l2);

System.out.println(l.toString()); //this will print [Abhishek, [Vishvendra]]        

l1.add("Rushikesh");
l2.add("Talina");

System.out.println(l.toString()); //now this will print [Abhishek, [Vishvendra, Talina]]
listl=newarraylist();
列表l1=新的ArrayList();
l1.添加(“阿披实”);
列表l2=新的ArrayList();
l2.添加(“Vishvendra”);
l、 addAll(l1);
l、 添加(l2);
System.out.println(l.toString())//这将印刷[阿披舍克[维什文德拉]]
l1.添加(“Rushikesh”);
l2.添加(“塔利纳”);
System.out.println(l.toString())//现在这将印刷[阿披舍克,[维什文德拉,塔利纳]]
我想现在很容易理解了。
检查addAll()方法的行为。

的可能重复,因为
=
从不复制任何内容。@SLaks:嗯,它复制表达式的值。只是在这种情况下,该值是一个引用…=用于引用,而不是值itself@JonSkeet. 这个问题是否还没有一个规范的答案(仅在最近几天内似乎已经被问了好几次)?的可能重复,因为
=
从不复制任何东西。@SLaks:嗯,它复制表达式的值。只是在这种情况下,该值是一个引用…=用于引用,而不是值itself@JonSkeet. 这个问题(仅仅在过去几天里似乎已经被问了好几次)还没有一个规范的答案吗?