引用传递、值传递、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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值