麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Java > 正文

基于序列化存取實現java對象深度克隆的方法詳解

2019-11-26 16:06:03
字體:
來源:轉載
供稿:網友
我們知道,在java中,將一個非原型類型類型的對象引用,賦值給另一個對象的引用之后,這兩個引用就指向了同一個對象,如:
復制代碼 代碼如下:

public class DeepCloneTest {

 private class CloneTest {
  private Long myLong = new Long(1);
 }

 public static void main(String args[]) {
  new DeepCloneTest().Test();
 }

 public void Test() {
  CloneTest ct1 = new CloneTest();
  CloneTest ct2 = ct1;

  // to see if ct1 and ct2 are one same reference.
  System.out.println("ct1: " + ct1);
  System.out.println("ct2: " + ct2);

  // if ct1 and ct2 point to one same object, then ct1.myLong == ct2.myLong.
  System.out.println("ct1.myLong: " + ct1.myLong);
  System.out.println("ct2.myLong: " + ct2.myLong);

  // we change ct2's myLong
  ct2.myLong = 2L;

  // to see whether ct1's myLong was changed.
  System.out.println("ct1.myLong: " + ct1.myLong);
  System.out.println("ct2.myLong: " + ct2.myLong);
 }
}

out put:
ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@c17164
ct1.myLong: 1
ct2.myLong: 1
ct1.myLong: 2
ct2.myLong: 2
這個很easy,估計學java的都知道(不知道的是學java的么?)。
在內存中,對象的引用存放在棧中,對象的數據,存放在堆中,棧中的引用指向了堆中的對象。這里就是兩個棧中的引用,指向了堆中的同一個對象,所以,當改變了 ct2 的 myLong,可以看到,ct1 的 myLong 值也隨之改變,如果用圖來表示,就很容易理解了:


左邊的是棧區,該區中有兩個引用,值相同,它們指向了右邊堆區的同一個對象。
大多時候,我們會用 java 語言的這一特性做我們想做的事情,比如,將對象的引用作為入參傳入一個方法中,在方法中,對引用所指對象做相應修改。但有時,我們希望構造出一個和已經存在的對象具有完全相同的內容,但引用不同的對象,為此,可以這樣做
復制代碼 代碼如下:

public class DeepCloneTest{

 // must implements Cloneable.
 private class CloneTest implements Cloneable{
  private Object o = new Object();

  public CloneTest clone() {
   CloneTest ct = null;
   try {
    ct = (CloneTest)super.clone();
   } catch (CloneNotSupportedException e) {
    e.printStackTrace();
   }
   return ct;
  }
 }

 public static void main(String args[]) {
  new DeepCloneTest().Test();
 }

 public void Test() {
  CloneTest ct1 = new CloneTest();
  CloneTest ct2 = ct1.clone();

  // to see if ct1 and ct2 are one same reference.
  System.out.println("ct1: " + ct1);
  System.out.println("ct2: " + ct2);

  // whether ct1.o == ct2.o ? yes
  System.out.println("ct1.o " + ct1.o);
  System.out.println("ct1.o " + ct1.o);
 }
}

out put:
ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@1fb8ee3
ct1.o java.lang.Object@61de33
ct1.o java.lang.Object@61de33
從輸出可以看出:ct1 和 ct2 確實是兩個不同的引用,所以我們想當然的認為,ct1.o 和 ct2.o 也是兩個不同的對象了,但從輸出可以看出并非如此!ct1.o 和 ct2.o 是同一個對象!原因在于,雖然用到了克隆,但上面只是淺度克隆,用圖形來表示:


看到上面的 o 了么?其實是兩個對象共享的。這就相當于,你本來有一個羊圈1,里面有一只羊,然后你又弄了一個羊圈2,在不將羊從羊圈1里牽出來的情況下,將羊也圈在了羊圈2中,你以為你有兩條羊了,其實呢?大家都知道。

這就是淺度克隆的結果:如果你想讓兩個對象具有獨立的 o,就必須再對 o 做克隆操作。可能有些人認為這沒有什么,做就做唄,但想過沒有,如果不止一個 o, 還有很多很多的類似 o 的東東,你都逐一去做克隆嗎?顯然是不太現實的。

一種解決方法是:將對象先序列化存儲到流中,然后再從留中讀出對象,這樣就可以保證讀取出來的數據和之前的對象,里面的值完全相同,就像是一個完全的拷貝。
復制代碼 代碼如下:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class DeepCloneTest {

 // must implements Cloneable.
 private class CloneTest implements Serializable{
  private static final long serialVersionUID = 1L;
  private Object o = new Object();

  public CloneTest deepClone() {
   CloneTest ct = null;
   try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos);
             oos.writeObject(this);
             ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
             ObjectInputStream ois= new ObjectInputStream(bais);
             ct = (CloneTest)ois.readObject();
   } catch (IOException e) {
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
   return ct;
  }
 }

 public static void main(String args[]) {
  new DeepCloneTest().Test();
 }

 public void Test() {
  CloneTest ct1 = new CloneTest();
  CloneTest ct2 = ct1.deepClone();

  // to see if ct1 and ct2 are one same reference.
  System.out.println("ct1: " + ct1);
  System.out.println("ct2: " + ct2);

  // whether ct1.o == ct2.o ? no
  System.out.println("ct1.o " + ct1.o);
  System.out.println("ct1.o " + ct1.o);
 }
}

這個時候,內存中的數據就是這樣的了:


克隆任務完成。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久成人综合视频 | 激情影院在线观看 | 久久精品伊人网 | 日夜操天天干 | 日本一区免费看 | 色阁五月 | 欧美电影在线观看 | 色淫网站免费视频 | 一级国产免费 | 少妇的肉体k8经典 | 久久精品亚洲精品国产欧美kt∨ | 精品不卡| 精品国产一区二区三区四区在线 | 国产精品久久久久久久久久久久久久久久 | 三级国产三级在线 | 日产精品一区二区三区在线观看 | 国产一区二区三区四区精 | 国产精品久久久久久久午夜片 | 欧美www | 国产精品视频一区二区三区四区国 | 日韩精品一区二区三区中文 | 青草视频在线观看视频 | 久草在线最新 | 国产91精品亚洲精品日韩已满 | 国产精品久久久久av | 日韩美香港a一级毛片 | 欧美.com| 特级黄色影院 | 国产美女视频一区二区三区 | 久久精品视频免费观看 | 久久久国产精品视频 | 最新中文字幕第一页视频 | 欧美黄色试片 | 久久精品视频网站 | 久草在线播放视频 | 欧美性生交xxxxx久久久缅北 | 中文字幕在线看第二 | 久久久久久久久久久亚洲 | 福利在线免费 | 午夜视频成人 | 亚洲一区二区中文字幕在线观看 |