在 Java 中,什么是浅拷贝?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1175620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:32:18  来源:igfitidea点击:

In Java, what is a shallow copy?

javacloneshallow-copy

提问by Will

java.util.Calendar.clone() returns "...a new Calendar with the same properties" and returns "a shallow copy of this Calendar".

java.util.Calendar.clone() 返回“...具有相同属性的新日历”并返回“此日历的浅拷贝”。

This does not appear to be a shallow copy as answered hereon SO. That question is tagged language-agnostic,Java does not seem to follow the language agnostic definition. As I step through the code I notice that the structure and the elements are copied to this new object, more than the language agnostic structure only.

为回答这并不似乎是一个浅拷贝这里的SO。这个问题被标记为与语言无关,Java 似乎没有遵循与语言无关的定义。当我逐步执行代码时,我注意到结构和元素被复制到这个新对象,而不仅仅是语言不可知的结构。

In Java, what is a shallow copy?

在 Java 中,什么是浅拷贝?

How does it differ from a Java deep copy (if that exists)?

它与 Java 深拷贝(如果存在)有何不同?

采纳答案by KitsuneYMG

A shallow copy just copies the values of the references in the class. A deep copy copies the values. given:

浅拷贝只是复制类中引用的值。深拷贝复制值。给出:

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  

In this case the shallow copy has the same reference (==) and the deep copy only has an equivalent reference (.equals()).

在这种情况下,浅拷贝具有相同的引用 ( ==),而深拷贝只有等效的引用 ( .equals())。

If a change is made to the value of a shallowly copied reference, then the copy reflects that change because it shares the same reference. If a change is made to the value of a deeply copied reference, then the copy does not reflect that change because it does not share the same reference.

如果对浅拷贝引用的值进行了更改,则该副本会反映该更改,因为它共享相同的引用。如果对深度复制引用的值进行了更改,则该副本不会反映该更改,因为它不共享相同的引用。

C-ism

主义

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

Result:

结果:

a is 11  
*b is 11  
c is 10

回答by Tom Hawtin - tackline

The 1.6 docs document Calendar.cloneas "Creates and returns a copy of this object." A literal shallow copy as specified by Object.clonewouldn't make any sense. Java uses the term "shallow copy" in a fairly typical sense.

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

回答by Kevin Montrose

Where are you getting this documentation?

你从哪里得到这个文件?

The official Java 6 docs on java.sun.com simply have Calendar.clone()returning a copy of the object. No mention of shallow.

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

More generally, a shallow copy in Java is one where you get a new object reference but the new object holds (directly or indirectly) references to data in the original.

更一般地说,Java 中的浅拷贝是您获得新对象引用但新对象(直接或间接)保存对原始数据的引用的情况。

For example:

例如:

class MyClass{
  private List<Integer> innerList;

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

  //Some code...

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

returns a shallow copy in its clone().

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

回答by Chathuranga Chandrasekara

Shallow copy is a just a set of pointers to the same memory locations. Actually it does not create a real copy so the memory usage is lower.

浅拷贝只是一组指向相同内存位置的指针。实际上它不会创建真正的副本,因此内存使用率较低。

In a case of a deep copy, an exact copy of the memory segment is created and pointers are set to new memory locations. So theoritically the memory consumption should be twice in this case.

在深度复制的情况下,会创建内存段的精确副本,并将指针设置为新的内存位置。所以理论上在这种情况下内存消耗应该是两倍。

回答by mnuzzo

A shallow copy is a copy of the reference pointer to the object, whereas a deep copy is a copy of the object itself. In Java, objects are kept in the background, what you normally interact with when dealing with the objects is the pointers. The variable names point to the memory space of the object. A shallow copy is made when you set one variable equal to another like so:

浅拷贝是指向对象的引用指针的拷贝,而深拷贝是对象本身的拷贝。在 Java 中,对象保留在后台,您在处理对象时通常会与之交互的是指针。变量名指向对象的内存空间。当您将一个变量设置为等于另一个变量时,会生成一个浅拷贝,如下所示:

Object B = A;

A deep copy could be made by getting the properties of object A and putting them in a new object B.

通过获取对象 A 的属性并将它们放入新对象 B 中,可以进行深度复制。

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

This affects program behavior in that if you make a shallow copy and perform a task on it, that affects all shallow copies of the object. If you make a change to a deep copy, only that copy is affected. I hope this is detailed enough for you.

这会影响程序行为,因为如果您制作浅拷贝并对其执行任务,则会影响对象的所有浅拷贝。如果对深层副本进行更改,则只会影响该副本。我希望这对你来说足够详细。

回答by jsight

It appears to be a mistake in the documentation. I don't see how anything that Android's Calendar.clone method does meets the typical definition (in Java or otherwise) of a "shallow copy".

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

回答by mark

First of all, the Javadoc of ArrayList is somewhat wrong if we are talking about one-dimensional arrays, as it uses the method copyOf in Arrays. So clone() gives back a one-dimensional copy, at least since 1.5 (I didn't test further)! So that's what "shallow" means in Java: one-dimensional

首先,如果我们谈论一维数组,ArrayList 的 Javadoc 有点错误,因为它使用了 Arrays 中的方法 copyOf。所以 clone() 返回一个一维副本,至少从 1.5 开始(我没有进一步测试)!所以这就是 Java 中“浅”的意思:一维

You can read more here: http://www.javapractices.com/topic/TopicAction.do?Id=3. So clone() is no shallow copy! If you want a real shallow copy of a one-dimensional array, just reference it:

您可以在此处阅读更多信息:http: //www.javapractices.com/topic/TopicAction.do?Id=3。所以 clone() 不是浅拷贝!如果你想要一维数组的真正浅拷贝,只需引用它:

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

Arrays in Java are tricky, also because Java does pass-by-value, but the values of arrays are only their pointers! In the other hand this allows us to synchronize the objects, which is a great thing. Still, there are some problems if you use arrays within arrays (or ArrayLists), because a clone() of the container array (or ArrayList) won't copy their values, only their references! So you simply shouldn't put any arrays into an array, you should only deal with objects in an array!

Java 中的数组很棘手,也因为 Java 确实按值传递,但数组的值只是它们的指针!另一方面,这允许我们同步对象,这是一件好事。尽管如此,如果您在数组(或 ArrayLists)中使用数组,仍然存在一些问题,因为容器数组(或 ArrayList)的 clone() 不会复制它们的值,只会复制它们的引用!所以你根本不应该把任何数组放入数组中,你应该只处理数组中的对象!

And Javadoc is difficult to understand sometimes, so give testing a try...

而且 Javadoc 有时难以理解,因此请尝试进行测试...

Have fun!

玩得开心!

回答by Akanksha

A shallow copy just copies the object reference into the target reference. It does not create a new object on the heap. By default, Java does shallow cloning using clone() function.

浅拷贝只是将对象引用复制到目标引用中。它不会在堆上创建新对象。默认情况下,Java 使用 clone() 函数进行浅层克隆。

To get a new object on the heap, one has to perform deep cloning which can be implemented by Serialization and De-serialization.

要在堆上获得一个新对象,必须执行深度克隆,这可以通过序列化和反序列化来实现。

回答by pndey

In a shallow copy,the clone object has a copy of primitive values but the object references refer to the same objects as the original copy. Shallow Copies have a significant drawback, cloned object and original copy refer to the same address object. Any change that cloned object makes in address object will also be reflected in original copy, which is an unwanted behaviour. What we really wanted is two separate copies of user object. Deep copying comes to our rescue for this kind of situation.

在浅拷贝中,克隆对象具有原始值的副本,但对象引用引用与原始副本相同的对象。浅拷贝有一个明显的缺点,克隆对象和原始副本指向同一个地址对象。克隆对象在地址对象中所做的任何更改也将反映在原始副本中,这是一种不需要的行为。我们真正想要的是用户对象的两个独立副本。对于这种情况,深度复制可以帮助我们解决问题。

Deep copying clones not just the primitive values, it also creates copies of object references.

深度复制不仅克隆原始值,还创建对象引用的副本。

You can have a look at working example on this at here :https://codingninjaonline.com/2017/11/09/deep-vs-shallow-copy/

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

回答by Neeraj

Shallow Copy : In this cloning any changes to Cloned Object is reflected to Original Object also.

浅拷贝:在此克隆中,对克隆对象的任何更改也会反映到原始对象。

Deep Copy : In this cloning a separate cloned memory is alloted which means any changes to cloned object will not be reflected to original object.

深度复制:在此克隆中分配了单独的克隆内存,这意味着对克隆对象的任何更改都不会反映到原始对象。