java深度複製
參考:Java 實現深度複製
什麼是深度複製?在Java裡面,在建立一個物件,我們通常會有一個引用指向該物件,當我們通過引用變數改變物件的值(屬性)時,引用是不變的,變的是記憶體裡面的那塊記憶體,即引用所指向的物件。一般情況下,我們將該引用賦給另一個引用變數或者作為引數傳遞時,傳遞的也只是引用,即將引用指向“複製”了一份給另一個引用變數,隨後該引用變數也指向同一個物件,記憶體裡面並沒有建立一個新的物件。在某些情況下,我們需要“真正複製”物件,建立一份已知物件的copy,而不僅僅“複製”引用,用作備份也好,其他操作也好。
那麼,該如何實現?
先說下思路:首先將物件序列化到流裡,然後再反序列化,從流裡讀取出來即可。
java序列化和反序列化
- 概念
序列化:把Java物件轉換為位元組序列的過程。
反序列化:把位元組序列恢復為Java物件的過程。 - 用途
物件的序列化主要有兩種用途:
1) 把物件的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;
2) 在網路上傳送物件的位元組序列。 - 物件序列化
java.io.ObjectOutputStream代表物件輸出流,它的writeObject(Object obj)方法可對引數指定的obj物件進行序列化,把得到的位元組序列寫到一個目標輸出流中。只有實現了Serializable和Externalizable介面的類的物件才能被序列化。
java.io.ObjectInputStream代表物件輸入流,它的readObject()方法從一個源輸入流中讀取位元組序列,再把它們反序列化為一個物件,並將其返回。
java物件序列化條件
- 實現Serializable介面
- declare a static final serialVersionUID field of type long
常用序列化方法
- 序列化
// 位元組陣列輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 物件輸出流
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 序列化
oos.writeObject(new Integer(100)); //序列化整數100
2.反序列化
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Object o = ois.readObject();
例項:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
*
* @author Administrator
* 深度複製
*/
public class App2 {
public static void main(String[] args) throws Exception {
/******************** 寫入(序列) **********************/
// 位元組陣列輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 物件輸出流
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 序列化
oos.writeObject(new Integer(100));
oos.writeObject("Hello World");
oos.writeObject(new Cat("xiaohu",18));
oos.close();
baos.close();
/******************** 讀取(反序列) **********************/
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Object o = ois.readObject();
System.out.println(o);
o = ois.readObject();
System.out.println(o);
Cat cat = (Cat)ois.readObject();
System.out.println("name: "+cat.getName()+" age: "+cat.getAge());
ois.close();
bais.close();
}
}
Cat類:
import java.io.Serializable;
/**
* javaBean
*/
public class Cat implements Serializable {
private static final long serialVersionUID = 1861516170581376793L;
private String name;
private int age;
private String color ;
private int xx ;
//臨時的
private transient Person owner ;
private Dog neibor ;
public Dog getNeibor() {
return neibor;
}
public void setNeibor(Dog neibor) {
this.neibor = neibor;
}
public Person getOwner() {
return owner;
}
public void setOwner(Person owner) {
this.owner = owner;
}
public int getXx() {
return xx;
}
public void setXx(int xx) {
this.xx = xx;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Cat() {
System.out.println("()");
}
public Cat(String name, int age) {
super();
System.out.println("(1)");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Person類
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = -3860831553852022224L;
private String name ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Dog類:
package com.it18zhang.test;
import java.io.Serializable;
public class Dog implements Serializable{
private static final long serialVersionUID = 264736816365982588L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
總結:
- java深度複製非常實用,特別是在分散式應用當中,比如Hadoop,Spark等當中,通常採用主流的序列化框架如protobuf,avro,thrift等將資料物件進行序列化成位元組陣列,然後通過rpc(遠端過程呼叫)的機制通過通訊協議進行傳輸,從而實現分散式應用之間的通訊。在節省網路頻寬和磁碟io的基礎上更加提高了網路傳輸的效率和安全性。
- 完成RPC 需要兩個協議: 物件序列化協議 和 呼叫控制協議
相關文章
- js深度複製物件JS物件
- Java引用複製、淺複製、深複製Java
- JS物件深度克隆/複製JS物件
- javascript 陣列的深度複製JavaScript陣列
- 分散式Redis深度歷險-複製分散式Redis
- Java NIO - 零複製Java
- Java中物件的深複製和淺複製詳解Java物件
- C++再議建構函式及複製建構函式深度複製C++函式
- Java 中的深複製和淺複製你瞭解嗎?Java
- 物件的生存期 記憶體 深度複製 複製建構函式 筆記物件記憶體函式筆記
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- Java-IO:複製檔案Java
- Java NIO複製檔案功能Java
- Java: 複製檔案最快方法Java
- 深度解讀《深度探索C++物件模型》之複製建構函式C++物件模型函式
- JS物件複製:深複製和淺複製JS物件
- Linux 和 Java 的零複製LinuxJava
- [java IO流]之檔案複製Java
- Java物件複製之MapStruct使用Java物件Struct
- poi操作excel,複製sheet,複製行,複製單元格,複製styleExcel
- 淺複製、深複製與序列化【初級Java必需理解的概念】Java
- MySQL 8 複製(三)——延遲複製與部分複製MySql
- 使用結構化克隆在 JavaScript 中進行深度複製JavaScript
- java Arrays.copyOf實現淺複製Java
- 主從複製、雙主複製及半同步複製、以及基於SSL的複製
- MySQL主從複製、半同步複製和主主複製MySql
- JavaScript 淺複製和深複製JavaScript
- mysql複製--主從複製配置MySql
- MySQL主從複製、半同步複製和主主複製概述MySql
- Java IO 流之拷貝(複製)檔案Java
- java進階(34)--File類、目錄複製Java
- Java 中的寫時複製 (Copy on Write, COW)Java
- Java物件複製原理剖析及最佳實踐Java物件
- java複製檔案時遇到的問題Java
- MySQL 8 複製(一)——非同步複製MySql非同步
- MySQL 8 複製(二)——半同步複製MySql
- go slice深複製和淺複製Go
- MySQL主從複製_複製過濾MySql