Java深浅拷贝

深浅拷贝 Java

1. 前提

  • 深浅拷贝的前提是当拷贝一个对象时,即生成一个新的对象时。

  • 生成一个新的对象,主要有以下工作

    1. 内存分配一块和被拷贝的类一样的区域

    2. 划分字段,方法的使用区域

    3. 将被拷贝类内存里的内容搬到指定区域

2. 怎么搬?

 - 前提中说到把被拷贝类内存里的内容搬到新的区域,怎么搬呢?我的理解就是简单的赋值。

   ```java
   class Person{
       public int age;
       public String name;
       
       public Person(){
           
       }
       
       public Person(int m_age, String m_name){
           age = m_age;
           name = m_name;
       }
   }
   // 拷贝的过程类似如下
   Person per = new Person(12, "Fizz");
   Person oth = new Person();
   oth.age = per.age;
   oth.name = per.name
   ```

   - 简单的赋值有问题吗?对于引用型变量和基本数据类型有啥不同?

     1.对于基本数据类型,=相当于赋值内容,而对于引用变量,= 只是传递对象的地址。

     2. 所以oth.name 和per.name共用一个String对象。而对于age字段,是基本数据类型,所以oth.age和per.name各自拥有一个int值。

3. 结论

  • 在拷贝被过程中,对于引用型的字段,只是简单的赋值操作,而没有生成一个新的对象,叫做浅拷贝。
  • 在拷贝过程中,对于引用型的字段,生成一个一个新的对象,区别在于对象地址不同了,叫做深拷贝。

4. Java如何实现拷贝

  • Object类具有一个clone的native方法,c++实现。

  • 被拷贝的类实现Cloneable接口,并重写clone方法即可。

    package com;
    
    import java.util.Objects;
    
    public class TestStr {
    
        public static void main(String[] args) {
            Person per = new Person("fizz", 5);
            Person oth = per.clone();
            System.out.println(per==oth);// false 
            System.out.println(per.name == oth.name);// false
        }
        
    }
    
    class Person implements  Cloneable{
        String name;
        int age;
    
        Person(String m_name, int m_age){
            name = m_name;
            age = m_age;
        }
    
    
        @Override
        public Person clone(){
            try{
            Person cloneob = (Person) super.clone();//spuer.clone()最终会到达Object.clone()。浅拷贝,对象内部成员只是简单的赋值,c++实现。
            cloneob.name = new String(this.name);//拷贝字符串对象
            return cloneob;
            }catch (CloneNotSupportedException e){
                System.out.println(e);
            }
            return null;
        }
    }
    

    5. 思考

    • 这个问题其实就是c++中赋值构造函数,实现一个对象的拷贝,看来c++还是得复习复习。
posted @ 2020-08-06 18:50  FizzPu  阅读(143)  评论(0编辑  收藏  举报