1. 程式人生 > 實用技巧 >Java深淺拷貝

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++還是得複習複習。