在Java中,什么是浅副本?

2022-08-31 16:04:20

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

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

在Java中,什么是浅副本?

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


答案 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

答案 2

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

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