Java實現(xiàn)對象復制的方法實例
一、概念
1.淺復制:復制出來的對象中的變量(包括基本類型和字符串)和原來的對象的值都相同,但是引用對象仍然指向原來的對象。
2.深復制:復制出來的對象中的變量(包括基本類型和字符串)和原來的對象的值都相同,引用對象也會指向復制出來的對象。
淺復制與深復制的不同之處就在于深復制還會復制對象的引用對象。
二、實現(xiàn)復制
1.使用Cloneable接口實現(xiàn)對象的復制
⑴淺復制
代碼如下
public class Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}public class Animal implements Cloneable {
// 動物名
private String name;
// 食物
private Food food;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public Animal clone() {
Animal animal = null;
try {
animal = (Animal) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return animal;
}
}public class TestCopy {
public static void main(String[] args) {
Food food = new Food();
food.setName("草");
Animal animal = new Animal();
animal.setName("羊");
animal.setFood(food);
Animal animal2 = animal.clone();
System.out.println("animal動物名:"+animal.getName());
System.out.println("animal食物名:"+animal.getFood().getName());
System.out.println("animal2動物名:"+animal2.getName());
System.out.println("animal2食物名:"+animal2.getFood().getName());
}
}打印結果是
animal動物名:羊
animal食物名:草
animal2動物名:羊
animal2食物名:草
此時已成功的實現(xiàn)了復制,但是這只是淺復制,引用對象Food并沒有被復制。
驗證代碼
public class TestCopy {
public static void main(String[] args) {
Food food = new Food();
food.setName("草");
Animal animal = new Animal();
animal.setName("羊");
animal.setFood(food);
Animal animal2 = animal.clone();
System.out.println("animal動物名:"+animal.getName());
System.out.println("animal食物名:"+animal.getFood().getName());
System.out.println("animal2動物名:"+animal2.getName());
System.out.println("animal2食物名:"+animal2.getFood().getName());
//改變animal中food對象的值
food.setName("樹葉");
System.out.println("animal動物名:"+animal.getName());
System.out.println("animal食物名:"+animal.getFood().getName());
System.out.println("animal2動物名:"+animal2.getName());
System.out.println("animal2食物名:"+animal2.getFood().getName());
}
}打印結果是
animal動物名:羊
animal食物名:草
animal2動物名:羊
animal2食物名:草
animal動物名:羊
animal食物名:樹葉
animal2動物名:羊
animal2食物名:樹葉
結果證明改變animal中的引用對象food,同時也改變了animal2中的引用對象food,說明animal和animal2的引用對象food是同一對象。
⑵深復制
要實現(xiàn)深復制,就必須同時復制引用對象,引用對象需實現(xiàn)Cloneable接口,F(xiàn)ood修改如下
public class Food implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Food clone() {
Food food = null;
try {
food = (Food) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return food;
}
}Animal修改如下
public class Animal implements Cloneable {
// 動物名
private String name;
// 食物
private Food food;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public Animal clone() {
Animal animal = null;
try {
animal = (Animal) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//復制引用對象
animal.food = food.clone();
return animal;
}
}在clone方法中添加了引用對象的復制
使用上面的main方法測試,打印結果如下
animal動物名:羊
animal食物名:草
animal2動物名:羊
animal2食物名:草
animal動物名:羊
animal食物名:樹葉
animal2動物名:羊
animal2食物名:草
結果證明animal和animal2的引用對象food已經不是同一對象了,此時成功地實現(xiàn)了深復制。
2.使用序列化(Serializable接口)實現(xiàn)對象的復制
使用Cloneable接口每個類都需要寫clone方法,工作量是很大的,我們可以使用序列化來實現(xiàn)對象的拷貝,這需要對象實現(xiàn)java.io.Serializable接口。
將上面的Animal和Food修改一下
import java.io.Serializable;
public class Food implements Serializable{
private static final long serialVersionUID = 6466656398591229036L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}import java.io.Serializable;
public class Animal implements Serializable {
private static final long serialVersionUID = -8424013303049171827L;
// 動物名
private String name;
// 食物
private Food food;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
}再寫一個復制的工具類
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class CopyUtil {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj) {
T cloneObj = null;
ByteArrayOutputStream baos = null;
ByteArrayInputStream bais = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
// 反序列化,生成新對象
bais = new ByteArrayInputStream(
baos.toByteArray());
ois = new ObjectInputStream(bais);
cloneObj = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(oos!=null){
oos.close();
}
if(baos!=null){
baos.close();
}
if(ois!=null){
ois.close();
}
if(bais!=null){
bais.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return cloneObj;
}
}測試代碼
public class TestCopy {
public static void main(String[] args) {
Food food = new Food();
food.setName("草");
Animal animal = new Animal();
animal.setName("羊");
animal.setFood(food);
Animal animal2 = CopyUtil.clone(animal);
System.out.println("animal動物名:"+animal.getName());
System.out.println("animal食物名:"+animal.getFood().getName());
System.out.println("animal2動物名:"+animal2.getName());
System.out.println("animal2食物名:"+animal2.getFood().getName());
//改變animal中food對象的值
food.setName("樹葉");
System.out.println("animal動物名:"+animal.getName());
System.out.println("animal食物名:"+animal.getFood().getName());
System.out.println("animal2動物名:"+animal2.getName());
System.out.println("animal2食物名:"+animal2.getFood().getName());
}
}打印結果如下
animal動物名:羊
animal食物名:草
animal2動物名:羊
animal2食物名:草
animal動物名:羊
animal食物名:樹葉
animal2動物名:羊
animal2食物名:草
利用序列化成功的實現(xiàn)了深復制。
到此這篇關于Java實現(xiàn)對象復制的方法實例的文章就介紹到這了,更多相關Java對象復制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring MVC之mvc:resources如何處理靜態(tài)資源
這篇文章主要介紹了Spring MVC之mvc:resources如何處理靜態(tài)資源問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn)
這篇文章主要介紹了Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-02-02
Spring Boot集成netty實現(xiàn)客戶端服務端交互示例詳解
這篇文章主要給大家介紹了關于Spring Boot集成netty實現(xiàn)客戶端服務端交互的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-12-12
SpringMVC實戰(zhàn)案例RESTFul實現(xiàn)添加功能
這篇文章主要為大家介紹了SpringMVC實戰(zhàn)案例RESTFul實現(xiàn)添加功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05

