引用傳遞、值傳遞、Shallow Copy & Deep Copy

Java值傳遞、引用傳遞

Java is always pass-by-value.若是基本數據類型,值爲數據值;若是引用數據類型,其存儲的是地址值。
【棧幀中局部變量表,存放基本數據類型變量和值;引用數據類型存放變量和對象地址值(堆中地址)),棧幀私有,堆中對象共享】

public class Main {

     public static void main(String[] args) {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }

     public static void changeReference(Foo a) {
          Foo b = new Foo("b");
          a = b;
     }

     public static void modifyReference(Foo c) {
          c.setAttribute("c");
     }

}

在這裏插入圖片描述
看更多例子:https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

一、what is a copy

分爲兩類:

  • reference copy:create a copy of a reference variable pointing to an object.
  • object copy:create a copy of the object itself.

在這裏插入圖片描述

二、Shallow Copy & Deep Copy

Both a Deep Copy and a Shallow Copy are types of object copies.
An object copy usually called a clone,is created if we want to modify or move an object, while still preserving the original object.

1. Shallow Copy

A shallow copy of an object copies the ‘main’ object, but doesn’t copy the inner objects. The ‘inner objects’ are shared between the original object and its copy.Shallow copy is not 100% independent of original object.
inner object也就是引用類型,它是reference copy。

public class Dog {
    private String name;
    private List<Child> childs ;
    
    public Dog(Dog dog) {
        this.name = dog.name;
        //shallow copy
        this.childs=dog.childs;  //reference copy
    }
}

測試

        List<Child> ls=new ArrayList<>();
        ls.add(new Child("child0"));
        Dog aDog = new Dog("Max",ls);
       
        Dog copyDog=new Dog(aDog);
        System.out.println(aDog==copyDog); //false
        System.out.println(aDog.getChilds()==copyDog.getChilds()); //true

在這裏插入圖片描述

2.Deep Copy

a deep copy is a fully independent copy of an object. If we copied our Person object, we would copy the entire object structure.

To create a true deep copy, we need to keep copying all of the Dog object’s nested elements, until there are only primitive types and “Immutables” left.
(基本數據類型存放在堆對象中,immutable若更改則會創建對象,並不會影響之前的值)

  public Dog(Dog dog) {
        this.name = dog.name;
        //deep copy
        this.childs=new ArrayList<>(dog.getChilds());
        //內部調用elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

在這裏插入圖片描述

三、Cloneable

如上,通過構造函數,可以實現深複製和淺複製。Java還提供了Cloneable接口,它是一個marker interface。

public class A implements Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return (A)super.clone();
    }
}
public class Dog implements Cloneable{

    private String name;
    private List<Child> childs ;
    private A a; //mutable fields所對應類也要實現Cloneable

    @Override
    protected Object clone() throws CloneNotSupportedException {
       // return super.clone(); //shadow copy
       //-------華麗的分割線-----------
       //deep copy
        cloneDog cl=(cloneDog)super.clone();
        /* primitive fields are ignored, as their content is already copied
          immutable fields like String are ignored

        create new objects for any non-primitive, mutable fields
        */
        cl.childs=new ArrayList<>(getChilds());
        cl.a=(A)this.a.clone();
        return cl;
    }
}

四、Shallow copy Vs Deep Copy

  1. Shallow copies are inexpensive and easy to implement.
    Deep copies are expensive as(因爲) each referenced object has to be created separately. It is also more complex as object tree may be very long.
  2. In case of shallow copy though a distinct copy of an object is created with its own set of fields but object references are shared.
    In case of deep copy even for the referenced objects separate copies are created.
  3. By default Object class’ clone method creates a shallow copy.
    For creating a deep copy you need to override clone method and call the clone method on the referenced objects too.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章