1. 程式人生 > >【Java基礎】物件拷貝

【Java基礎】物件拷貝

背景

如果不關注物件引用傳遞,這必將帶來的是悲劇,你將一個物件從一個模組交到了另一個模組而渾然不知,而當另一個模組在修改該物件的內容同時也默默的影響到之前的模組,這是很糟糕的,問題也很難找。

我們如何在編碼中警覺到這一點?

我們如何在編碼中警覺到這一點?以減少最後成為這種問題的受害者時候的尷尬呢?

準則一:B模組需要使用到A模組中的某物件值,B模組內對該物件值修改,你期望這會影響到A模組的該物件內容嗎?如果否,那就請用物件拷貝。一般為否。

準則二:當你的模組對外暴露方法介面提供物件,如果外界修改該物件內容,你期望這會影響到你自身模組的該物件內容嗎?如果否,那就請用物件拷貝。一般為否。

物件拷貝

淺拷貝

拷貝物件自身,但不拷貝物件內所引用的物件

class Student implements Cloneable  
{  
    public int age;  
    public String name;  
    public Teacher teacher;  
   /** 
    *  重寫clone()方法 
    * @return 
    */ 
    public Object clone() { 
      //淺拷貝 
      try { 
         // 直接呼叫父類的clone()方法
         return
super.clone(); } catch (CloneNotSupportedException e) { return null; } } }

深拷貝

除了拷貝物件自身,連同物件內所引用的物件也進行拷貝

一.巢狀clone方式

接上面淺拷貝,在自身物件clone執行的時候,也巢狀執行所引用物件的clone方法,並將clone物件設定到自身物件中。

@Override  
    public Object clone() throws CloneNotSupportedException  
    {  
        Student student = (Student) super
.clone(); // 將引用的物件teacher也clone下 student.setTeacher((Teacher) (student.getTeacher().clone())); return student; }

二.序列化方式

 /**
     * 深度拷貝 要求data物件及引用物件都實現了Serializable接口才可以用
     * @param data
     */
    public static <T> T deepCopy(T data) throws Exception {
        // 將該物件序列化成流,因為寫在流裡的是物件的一個拷貝,而原物件仍然存在於JVM裡面。所以利用這個特性可以實現物件的深拷貝
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(data);
        // 將流序列化成物件
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (T) ois.readObject();
    }

對比

從實現角度而言,方式二更加簡便,只需要實現Serializable,方式一,需要實現了Cloneable,還有clone方法。效率還不知道。

相關推薦

Java基礎物件拷貝

背景 如果不關注物件引用傳遞,這必將帶來的是悲劇,你將一個物件從一個模組交到了另一個模組而渾然不知,而當另一個模組在修改該物件的內容同時也默默的影響到之前的模組,這是很糟糕的,問題也很難找。 我們如何在編碼中警覺到這一點? 我們如何在編碼中警覺到這一點

Java基礎Json字串轉物件和轉List集合操作

to今天發現專案中需要拿到對接系統中傳值的Json,需要轉換成List集合。回顧下Json字串的操作,寫了個測試。 public class JsonToUtil {     private  static final  Logger log = LoggerFactor

java基礎單例設計模式:保證一個類在記憶體中的物件唯一性

摘要:單例設計模式解決的問題就是可以保證一個類在記憶體中的物件唯一性,必須對於多個程式使用同一個配置資訊物件時,就需要保證物件的唯一性。 單例設計模式有兩個表現形式:餓漢式和懶漢式。餓漢式開發時常用,

Java基礎----static關鍵字、程式碼塊、Main方法、匿名物件詳解

1.static關鍵字 static簡介 static是靜態的意思,是一個修飾符,能夠用於成員變數和成員屬性。 特點 能夠通過類名直接進行呼叫,被static修飾

Java基礎RTTI與反射之Java

start auth try dword star sse from tac sed 1 ; Example assembly language program -- 2 ; Author: Karllen 3 ; Date: revised 05/2014

轉載:Java基礎InputStream 、 InputStreamReader和BufferedReader

gen 結果 取字符 sys try eight string font buffer 來源:http://blog.csdn.net/zgljl2012/article/details/47267609 在Java中,上述三個類經常用於處理數據流,下面介紹一下三個類的

Java基礎Java常見的異常

java exception Java常見的異常1. java.lang.NullPointerException (空指針異常)調用了未經初始化的對象或者是不存在的對象2. java.lang.ClassNotFoundException 指定的類不存在3. java.lang.NumberForm

Java基礎Java基本數據類型與位運算

右移 數據 bits 類型 span 網上 height 使用 常數 1.賦值運算符 賦值使用操作符“=”。它的意思是“取右邊的值(即右值),把它復制給左邊(即左值)”。右值可以是任何 常數、變量或者表達式 (只要它能 生成

Java基礎Java運算符優先級

() logs 分享 body rowspan 單元 ima idt string 序列號 符號 名稱 結合性(與操作數) 目數 說明 1 . 點 從左到右

java基礎重寫equals()方法的同時要重寫hashCode()方法

而且 通過 才會 默認 什麽 需要 現在 ash 字段 1、 為什麽要重寫equals方法? 因為Object的equal方法默認是兩個對象的引用的比較,意思就是指向同一內存,地址則相等,否則不相等;如果你現在需要利用對象裏面字段的值來判斷是否相等,則重寫equals方法。

Java基礎基礎精華總結

  一:java概述(快速瀏覽): 1991 年Sun公司的James Gosling等人開始開發名稱為 Oak 的語言,希望用於控制嵌入在有線電視交換盒、PDA等的微處理器; 1994年將Oak語言更名為Java;   Java的三種技術架構: JAVA

Java基礎註解(Annotation)

  Annotation,程式碼裡的特殊標記,在編譯、類載入、執行時被讀取,並執行相應的處理。 使用註解,在不改變原有邏輯的情況下,在原始檔中嵌入一些補充資訊。 Annotation提供了一種為程式元素設定元資料的方法。 Ann

Java基礎-多重For迴圈的兩種跳出方式

先來小段Demo,自己跑一下就能看到效果了: public static void main(String[] args) { List<String> listA = new ArrayList<String>(); List<String> lis

Java基礎程式碼塊,構造程式碼塊,靜態程式碼塊

程式碼塊 public class Demo { public static void main(String[] args){ { int a = 1; System.out.println(a); }

Java基礎static關鍵字

通過static宣告的屬性或者方法可以通過類名稱直接呼叫 static方法只能呼叫static屬性或者方法,不能呼叫非static屬性或者方法 非static方法則不受限,可以任意呼叫static宣告的屬性或者方法 注意:main方法本身就是一個static方法 示例1:static方法呼叫

Java基礎Java 基本資料型別

Java 的兩大資料型別: 內建資料型別 Java語言提供了八種基本型別。六種數字型別(四個整數型,兩個浮點型),一種字元型別,還有一種布林型。 byte: byte 資料型別是8位、有符號的,以二進位制補碼錶示的整數; 最小值是 -1

Java基礎String,StringBuffer,StringBuilder之間的區別

對於這三個類,先總體來理解一下: 對String,你建立了一個String,你能通過set方法改變它的長度length嗎?顯然是不行的! 但 StringBuffer 可以! String 字串常量 StringBuffer 字串變數(執行緒安全) StringBu

java基礎ConcurrentHashMap實現原理及原始碼分析

  ConcurrentHashMap是Java併發包中提供的一個執行緒安全且高效的HashMap實現(若對HashMap的實現原理還不甚瞭解,可參考我的另一篇文章),ConcurrentHashMap在併發程式設計的場景中使用頻率非常之高,本文就來分析下Concurre

Java基礎Hashmap

     hashMap實現Map介面,基於hashing原理,以鍵值對形式儲存,允許null鍵/值,非同步的集合型別;      hashmap的底層儲存結構是基於陣列和連結串列的。 一、put方法 public Object put(Object key,Obj

Java基礎int和Integer

Java中存在8種基本資料型別:byte(8位)、short(16位)、int(32位)、long(64位)、float(32位)、double(64位)、char(16位,0x0000~0xffff)、boolean(true/false) java中不存在無符號數字型別,