Java 對象的一共有 3 種複製對象的方式。ide
1.直接賦值 (引用複製 ),此種複製方式比較經常使用。this
諸如 A a = b ; a 是直接複製了b的引用 ,也就是說它倆指向的是同一個對象。 此時 a == b [ true ] 。spa
1 class A{ 2 private String string; 3 A(){string = new String("original state");} 4 public void set(String string) {this.string = string;} 5 public String get() {return string;} 6 } 7 8 public class B{ 9 public static void main(String[] args) { 10 // TODO 自動生成的方法存根 11 A a = new A(); 12 A b = a; 13 System.out.println(a == b); 14 a.set("state has changed"); 15 System.out.println(a == b); 16 } 17 }
2.淺拷貝 ------- 複製當前對象的非靜態字段【靜態字段只在類加載的時候加載一次】,若是當前字段爲 值類型 字段,那麼直接複製該字段,若是是 引用類型 的,則對其複製引用。3d
所謂的值類型就是指Java中的8種基本類型,那麼什麼是值類型的複製呢?code
舉個例子 int A = 0; int B = A; 那麼這樣B拷貝的是A指向的常量對象,而非A的引用,當A改變時,並不會影響B的指向。【Ps: A =1; 則B = 0 ,而非 1 , 這就是值類型的複製】對象
所謂的引用類型就是一些你本身構建的類和庫中的一些類實例化出來的對象,引用複製又指的啥呢?blog
舉個例子接口
class A {public int value = 0 ; } ====> A a = new A(); A b = a; =====> a.value = 1; 那麼 ==> b.value = 1; 由於它們指向的是同一個對象【複製的是引用】get
1 class B implements Cloneable{ 2 3 private C c; 4 5 private String string ; 6 public B() {string = new String("Init string"); c = new C();} 7 public void set(String string) {this.string = string;} 8 public String get() {return string;} 9 10 //setC()方法中添加一句 c = new C() ,就變爲深拷貝了,由於添加了 這句代碼, 拷貝 引用類型時,就變成拷貝其對象,而不是引用了 11 public void setC(String string) {c.set(string);} 12 public String getC() {return c.get();} 13 14 15 @Override 16 public Object clone() { 17 B sCopy = null; 18 try { 19 sCopy = (B)super.clone(); 20 }catch(Exception e) { 21 e.printStackTrace(); 22 } 23 return sCopy; 24 } 25 } 26 public static void main(String[] args) { 27 // TODO 自動生成的方法存根 28 29 30 B sCopyA = new B(); 31 B sCopyB = (B) sCopyA.clone(); 32 33 sCopyA.set("hava changed !"); 34 // sCopyA.string = hava changed ! ------- sCopyA.string = Init string 35 // 改變了 sCopyA 並無改變 sCopyB。 由於 B.string 是一個值類型 36 System.out.println("sCopyA.string = "+ sCopyA.get()+" ------- sCopyA.string = "+ sCopyB.get()); 37 38 sCopyB.setC("C have Changed !"); 39 // C.string = C have Changed ! ------- C.string = C have Changed ! 40 // 改變了 sCopyA 同時也改變 sCopyB。由於 B.string 是一個引用類型 41 System.out.println("C.string = "+ sCopyA.getC()+" ------- C.string = "+ sCopyB.getC()); 42 }
3.深拷貝 ------- 和淺拷貝的區別就在於,其無論字段類型是什麼,通通的全給拷貝過去【即便相對與 非基本類型而言 拷貝的也是對象而不是引用 ,深拷貝以後將會產生2個對象 ,淺拷貝只是一個對象的2個引用而已(至關於1我的的2個名字)】。string
咱們只要在 2的基礎上添加一行代碼就行, 由於只要將 引用字段,也進行復制 ,就是深拷貝了。
附:1.clone()方法 須要覆寫。 2.覆寫clone()方法須要實現Cloneable 接口, 未實現的話會拋出異常。 3 .clone()是本地方法,其內部實現以下圖。