java浅表副本_clone-在Java中,什么是浅表副本?

clone-在Java中,什么是浅表副本?

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

正如在SO上回答的那样,这似乎不是一个浅表副本。 该问题被标记为与语言无关,Java似乎没有遵循与语言无关的定义。 在我遍历代码时,我注意到结构和元素被复制到这个新对象,而不仅仅是语言不可知的结构。

在Java中,什么是浅表副本?

它与Java深层副本(如果存在)有何不同?

Will asked 2020-01-27T03:58:46Z

11个解决方案

76 votes

浅表副本仅复制类中引用的值。 深拷贝将复制值。 给出:

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

KitsuneYMG answered 2020-01-27T03:59:15Z

12 votes

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

在深拷贝的情况下,将创建内存段的精确副本,并将指针设置到新的内存位置。 因此,从理论上讲,在这种情况下,内存消耗应为两倍。

Chathuranga Chandrasekara answered 2020-01-27T03:59:40Z

5 votes

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

Object B = A;

通过获取对象A的属性并将其放在新的对象B中,可以进行深层复制。

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

这会影响程序的行为,因为如果您制作一个浅表副本并对其执行任务,则会影响该对象的所有浅表副本。 如果更改深层副本,则仅会影响该副本。 希望对您足够详细。

mnuzzo answered 2020-01-27T04:00:11Z

3 votes

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

Tom Hawtin - tackline answered 2020-01-27T04:00:31Z

2 votes

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

jsight answered 2020-01-27T04:00:51Z

1 votes

您从哪里获得此文档?

java.sun.com上的官方Java 6文档仅具有Calendar.clone()返回该对象的副本。 不提浅。

通常,Java中的浅表副本是您获得新对象引用但新对象(直接或间接)持有对原始数据的引用的副本。

例如:

class MyClass{

private List innerList;

public MyClass(List list) { innerList = list; }

//Some code...

public Object clone(){

return new MyClass(innerList);

}

}

在其clone()中返回浅表副本。

Kevin Montrose answered 2020-01-27T04:01:29Z

1 votes

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

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

Akanksha answered 2020-01-27T04:01:54Z

0 votes

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

您可以在此处了解更多信息:[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

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

而且Javadoc有时很难理解,因此请尝试一下测试...

玩得开心!

mark answered 2020-01-27T04:02:33Z

0 votes

在浅表副本中,克隆对象具有原始值的副本,但是对象引用所引用的对象与原始副本相同。浅副本有一个明显的缺点,克隆对象和原始副本引用相同的地址对象。 克隆对象对地址对象所做的任何更改也将反映在原始副本中,这是不希望有的行为。 我们真正想要的是用户对象的两个单独副本。 在这种情况下,深层复制可为我们提供帮助。

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

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

pndey answered 2020-01-27T04:03:03Z

0 votes

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

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

Neeraj answered 2020-01-27T04:03:27Z

0 votes

浅拷贝是通过引用...DEEP COPY是按值传递…上下文不同,但是过程完全相同。 首先要记住,在Java方法调用中,基元是通过值传递的,而对象是通过引用传递的(在其他语言中,对象也可以通过值传递)。 现在,在Java中,当调用者将原语传递给被调用的方法时,被调用的方法只是将其克隆为新的局部变量,即深拷贝。 如果传递了对象,则被调用的方法将仅对同一对象进行新的本地引用,即浅拷贝。 如果您了解通话,就会了解深层/浅层复制,反之亦然。

answered 2020-01-27T04:03:48Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值