在Java中,什么是浅拷贝?(In Java, what is a shallow copy?)

2019-06-17 14:55发布

java.util.Calendar.clone()返回“......具有相同属性的新日历”,并返回‘此日历的浅表副本’。

为回答这并不似乎是一个浅拷贝这里的SO。 这个问题被标记语言无关,爪哇似乎并没有遵循语言无关的定义。 正如我通过代码我注意到,结构和元件被复制到该新的对象,超过仅语言无关的结构。

在Java中,什么是浅拷贝?

它是如何从一个Java深拷贝不同(如果存在)?

Answer 1:

浅表副本只是复制中的类的参考值。 深拷贝复制值。 给定:

class Foo {
  private Bar myBar;
  ...
  public Foo shallowCopy() {
    Foo newFoo = new Foo();
    newFoo.myBar = myBar;
    return newFoo;
  }

  public Foo deepCopy() {
    Foo newFoo = new Foo();
    newFoo.myBar = myBar.clone(); //or new Bar(myBar) or myBar.deepCopy or ...
    return newFoo;
  }
}

Foo myFoo = new Foo();  
Foo sFoo = myFoo.shallowCopy();  
Foo dFoo = myFoo.deepCopy();  

myFoo.myBar == sFoo.myBar => true  
myFoo.myBar.equals(sFoo.myBar) => true  
myFoo.myBar == dFoo.myBar => **false**  
myFoo.myBar.equals(dFoo.myBar) => true  

在这种情况下,浅副本具有相同的参考( == )和深层副本仅具有等效的参考( .equals()

如果进行了更改到浅复制基准的值进行,然后因为它共享相同的副本反映了这种变化。 如果进行了更改到深复制基准的值进行,则副本不反映这种变化,因为它不具有相同的参考。

C-主义

int a = 10; //init
int& b = a; //shallow - copies REFERENCE
int c = a;  //deep - copies VALUE
++a;

结果:

a is 11  
*b is 11  
c is 10


Answer 2:

浅拷贝是只是一组指向相同的内存位置。 其实这样的内存使用率较低不会创建一个真正的副本。

在的深层副本的情况下,将创建存储器段的精确副本和指针设置为新的存储位置。 所以theoritically内存消耗应该在这种情况下的两倍。



Answer 3:

浅表副本是参考指针对象的副本,而深层副本是对象本身的副本。 在Java中,对象保存在后台,你通常与对象打交道时与之交互的指针。 变量名指向该对象的存储空间。 当您设置一个变量等于另一个像这样一个浅拷贝是由:

Object B = A;

深副本可以通过获取对象A的性质,并把它们放在一个新的对象B.进行

Object B = new Object(A.getProperty1(), A.getProperty2()...);

这会影响该程序的行为,如果你犯了一个浅拷贝,并对其执行任务,影响对象的所有浅拷贝。 如果您更改到一个深拷贝,只拷贝受到影响。 我希望这是对你不够详细。



Answer 4:

1.6文档文件Calendar.clone为“创建并返回此对象的副本。” 字面上的浅拷贝由指定Object.clone将没有任何意义。 Java使用术语“浅拷贝”,在一个相当典型的意义。



Answer 5:

这似乎是在文档中是错误的。 我没有看到任何Android的Calendar.clone方法做如何满足典型的定义(在Java或其他方式)的“浅拷贝”。



Answer 6:

你在哪里得到这个文件?

java.sun.com上的官方Java 6文档只需Calendar.clone()返回对象的副本。 浅没有提及。

更一般地,浅拷贝在Java是一个你在哪里得到一个新的对象引用,但新的对象持有(直接或间接)在原始数据的引用。

例如:

class MyClass{
  private List<Integer> innerList;

  public MyClass(List<Integer> list) { innerList = list; }

  //Some code...

  public Object clone(){
    return new MyClass(innerList);
  }
}

在它的clone返回浅拷贝()。



Answer 7:

浅表副本只是复制对象引用到目标参考。 它不会在堆上创建一个新的对象。 默认情况下,Java那样使用的clone()函数浅克隆。

要获得堆上一个新的对象,就必须进行深刻的克隆可以通过序列化和反序列化来实现。



Answer 8:

首先,ArrayList中的Javadoc,是有点错的,如果我们谈论的是一维数组,因为它使用的阵列的方法copyOf。 因此,克隆()还给一维副本,至少从1.5(我没有进一步测试)! 所以,这就是“浅”是指在Java中:一维

你可以在这里阅读更多: http://www.javapractices.com/topic/TopicAction.do?Id=3 。 因此,克隆()不浅拷贝! 如果你想有一个一维数组的一个真正的浅拷贝,只是引用它:

Array a = new Array();
Array b = a;                    //a is only a shallow copy, nice for synchronisation

Java中的数组有猫腻,也因为Java不传址值,但是数组的值是他们的三分球! 在另一方面,这可以让我们的对象,这是一个伟大的事情同步。 不过,也有一些问题,如果你使用数组(或的ArrayList)内的数组,因为克隆()容器数组(或ArrayList中)不会复制他们的价值观,只有自己参考! 所以,你根本不应该把任何数组到一个数组,你应该只处理数组中的对象!

和Javadoc有时很难理解,所以给测试试...

玩得开心!



Answer 9:

在一个浅拷贝,克隆对象具有原始值的副本,但对象引用指向同一个对象作为原件。 浅拷贝有显著的缺点,克隆的对象和原件指的是同一个地址对象。 该克隆的对象使得地址对象的任何变化也将体现在原始拷贝,这是一个不受欢迎的行为。 我们真正需要的是用户对象的两个单独的副本。 深拷贝来拯救我们的这种情况。

深度复制克隆不只是原始值,它也创造对象引用的副本。

:你可以在这里看看工作示例这个https://codingninjaonline.com/2017/11/09/deep-vs-shallow-copy/



文章来源: In Java, what is a shallow copy?