`
kobe学java
  • 浏览: 262462 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java中的clone机制及序列化

    博客分类:
  • java
 
阅读更多

    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,AB是两个独立的对象,但B的初始值是由A对象确定的。在这种情况下常常使用clone。当然你完全可以new一个新的,让后再进行赋值。但应用clone会有如下的好处:

     1、实现clone方法比较简单、方便。

     2、Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法,因此clone方法是高效的。

    注意;通过序列化的方式也可以实现clone。如果一个对象包含复杂类型的变量时,可用序列化或深度clone来实现对象的clone。

 

浅度复制和深度复制

  
    在java中,对于基本类型的数据可采用浅度复制的方式进行对象的复制,其中做法就是直接继承Cloneable接口,调用Object类的clone()方法就可以了。而对于非基本类型的数据,复制方法只能采用深度复制或序列化的方式进行复制。
    典型的实例:
Java代码   收藏代码
  1. /** 
  2.  *  
  3.  * @功能   羊对象类   
  4.  * @创建人   gao_jie 
  5.  * @创建日期 Jun 25, 2009 
  6.  * @版本     1.0 
  7.  *  
  8.  */  
  9. public class Sheep implements Cloneable {  
  10.       
  11.     private String name;//名字  
  12.   
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.   
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20.       
  21.     /* (non-Javadoc) 
  22.      * @see java.lang.Object#clone() 
  23.      */  
  24.     public Object clone() throws CloneNotSupportedException {  
  25.         return super.clone();  
  26.     }  
  27. }  
  28.   
  29. public class Sheepfold implements Cloneable {  
  30.      public Sheep sheep;//羊对象  
  31.      public String name;//羊圈名字  
  32.      public int number;//数量  
  33.   
  34.      public Sheepfold() {  
  35.          this.sheep = new Sheep();  
  36.      }  
  37.     /* (non-Javadoc) 
  38.      * @see java.lang.Object#clone() 
  39.      */  
  40.     public Object clone() throws CloneNotSupportedException {  
  41.         return super.clone();  
  42.     }  
  43. }  
  44.   
  45. public class Test {  
  46.     public static void main(String[] args) {  
  47.         // 声明一个小羊圈对象  
  48.         Sheepfold smallFold = new Sheepfold();  
  49.         smallFold.name = "小羊圈";  
  50.         smallFold.number = 10;  
  51.         smallFold.sheep.setName("小羊");  
  52.         // 复制羊圈  
  53.         Sheepfold bigFold = null;  
  54.         try {  
  55.             bigFold = (Sheepfold) smallFold.clone();  
  56.         } catch (CloneNotSupportedException e) {  
  57.             // TODO Auto-generated catch block  
  58.             e.printStackTrace();  
  59.         }  
  60.         bigFold.name="大羊圈";  
  61.         bigFold.number=100;  
  62.         bigFold.sheep.setName("大羊");  
  63.           
  64.         System.out.println("小羊圈输出信息如下:");  
  65.         System.out.println("smallFold.name="+smallFold.name);  
  66.         System.out.println("smallFold.number="+smallFold.number);  
  67.         System.out.println("smallFold.sheep="+smallFold.sheep.getName());  
  68.         System.out.println("大羊圈输出信息如下:");  
  69.         System.out.println("bigFold.name="+bigFold.name);  
  70.         System.out.println("bigFold.number="+bigFold.number);  
  71.         System.out.println("bigFold.sheep="+bigFold.sheep.getName());  
  72.     }  
  73. }  
  74. 测试结果:  
  75. 小羊圈输出信息如下:  
  76. smallFold.name=小羊圈  
  77. smallFold.number=10  
  78. smallFold.sheep=大羊  
  79. 大羊圈输出信息如下:  
  80. bigFold.name=大羊圈  
  81. bigFold.number=100  
  82. bigFold.sheep=大羊  
 
显然上面的这种复制是失败的,因为改动第二个对象中的名字后第一个对象的名字也发生了变化。要实现正确的复制,必须采用深度复制。其sheepfold类中clone方法的代码应改为如下:

 

Java代码   收藏代码
  1. 把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为如下即可:  
  2.     public Object clone() throws CloneNotSupportedException {  
  3.         Sheepfold fold = (Sheepfold)super.clone();  
  4.         sheep = (Sheep)fold.sheep.clone();  
  5.         return fold;  
  6.     }  
 另外,采用序列化也可以实现深度复制的效果。
代码如下:

 

Java代码   收藏代码
  1. /** 
  2.  *  
  3.  * @功能   羊对象类   
  4.  * @创建人   gao_jie 
  5.  * @创建日期 Jun 25, 2009 
  6.  * @版本     1.0 
  7.  *  
  8.  */  
  9. public class Sheep implements Serializable{  
  10.       
  11.     private String name;//名字  
  12.   
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.   
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20. }  
  21.   
  22. public class Sheepfold implements Cloneable, Serializable {  
  23.     public Sheep sheep;// 羊对象  
  24.     public String name;// 羊圈名字  
  25.     public int number;// 数量  
  26.   
  27.     public Sheepfold() {  
  28.         this.sheep = new Sheep();  
  29.     }  
  30.   
  31.     /* 
  32.      * (non-Javadoc) 
  33.      *  
  34.      * @see java.lang.Object#clone() 
  35.      */  
  36.     public Object clone() throws CloneNotSupportedException {  
  37.         try {  
  38.             ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  39.             ObjectOutputStream oos = new ObjectOutputStream(bos);  
  40.             oos.writeObject(this);  
  41.             // 将流序列化  
  42.             ByteArrayInputStream bis = new ByteArrayInputStream(bos  
  43.                     .toByteArray());  
  44.             ObjectInputStream ois = new ObjectInputStream(bis);  
  45.             return ois.readObject();  
  46.         } catch (IOException e) {  
  47.             e.printStackTrace();  
  48.         } catch (ClassNotFoundException e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.         return null;  
  52.     }  
  53. }  
  54. 测试类  
  55. public class Test {  
  56.     public static void main(String[] args) {  
  57.         // 声明一个小羊圈对象  
  58.         Sheepfold smallFold = new Sheepfold();  
  59.         smallFold.name = "小羊圈";  
  60.         smallFold.number = 10;  
  61.         smallFold.sheep.setName("小羊");  
  62.         // 复制羊圈  
  63.         Sheepfold bigFold = null;  
  64.         try {  
  65.             bigFold = (Sheepfold) smallFold.clone();  
  66.         } catch (CloneNotSupportedException e) {  
  67.             // TODO Auto-generated catch block  
  68.             e.printStackTrace();  
  69.         }  
  70.         bigFold.name="大羊圈";  
  71.         bigFold.number=100;  
  72.         bigFold.sheep.setName("大羊");  
  73.           
  74.         System.out.println("小羊圈输出信息如下:");  
  75.         System.out.println("smallFold.name="+smallFold.name);  
  76.         System.out.println("smallFold.number="+smallFold.number);  
  77.         System.out.println("smallFold.sheep="+smallFold.sheep.getName());  
  78.         System.out.println("大羊圈输出信息如下:");  
  79.         System.out.println("bigFold.name="+bigFold.name);  
  80.         System.out.println("bigFold.number="+bigFold.number);  
  81.         System.out.println("bigFold.sheep="+bigFold.sheep.getName());  
  82.     }  
  83. }  
  84. 测试结果:  
  85. 小羊圈输出信息如下:  
  86. smallFold.name=小羊圈  
  87. smallFold.number=10  
  88. smallFold.sheep=小羊  
  89. 大羊圈输出信息如下:  
  90. bigFold.name=大羊圈  
  91. bigFold.number=100  
  92. bigFold.sheep=大羊  
 显然,序列化可以实现深度复制的效果,但每个非基本类型对象都必须是可序列化的。而设计模式中的原型啊模式也就是实现深度复制,因此,原型模式可以采用深度复制和序列化两种方式来实现。

 

分享到:
评论

相关推荐

    关于 Java 对象序列化您不知道的 5 件事

    在本文中,我们将深入探讨关于Java对象序列化你可能不知道的五件事情,这些知识点对于理解和优化你的Java应用程序至关重要。 1. **序列化的意义与用途** Java对象序列化不仅用于持久化对象状态,还能在网络传输中...

    07-Java序列化面试题(10题)-新增.pdf

    在 Java 中,序列化是一种用于处理对象流的机制,它可以将对象的内容进行流化,使其可以被读写和传输。下面是 10 个与 Java 序列化相关的面试题目: 1. 什么是 Java 序列化,如何实现 Java 序列化? Java 序列化是...

    JAVA_高级特性(hashCode,clone,比较器,Class反射,序列化)

    ### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。

    java Clone

    如果对象的成员变量是不可克隆的(如`final`字段或不可克隆的第三方类),则可能需要采用其他策略,比如序列化和反序列化,或者手动创建新对象并复制属性。 总之,Java的`clone`机制提供了复制对象的能力,通过实现...

    KryoJava序列化和克隆框架具有快速高效自动的特点

    7. **兼容性**:Kryo虽然不是Java标准的序列化机制,但它能很好地与其他Java库集成,如Google的Protocol Buffers或Apache Avro。 **Kryo的使用示例** 1. **初始化Kryo实例**: ```java Kryo kryo = new Kryo(); ...

    (完整word版)java6个机制.doc

    Java 语言中的六个核心机制包括克隆、序列化、多线程、异常处理、垃圾回收以及反射。在这里,我们将详细探讨前三个机制。 首先,让我们来看看克隆机制。克隆在编程中指的是复制一个对象并在内存中创建其副本。在 ...

    java-6个机制.doc

    Java的六个核心机制是编程中不可或缺的部分,它们包括克隆机制、序列化机制、多线程机制、反射机制以及垃圾回收机制和异常处理机制。在这篇文章中,我们将深入探讨前三个机制。 首先,克隆机制允许我们在内存中复制...

    Java利用序列化实现对象深度clone的方法

    有多种方式可以实现对象克隆,其中一种就是通过Java的序列化机制。序列化是将对象的状态转换为字节流的过程,而反序列化则是将字节流恢复为对象状态的过程。这种机制可以用来实现深度克隆,即不仅克隆对象本身,还...

    Java clone方法详解及简单实例

    Java中的`clone`方法是Java语言提供的一种复制对象的机制,它允许创建一个现有对象的副本,这个副本具有与原始对象相同的状态,但它们是独立的实体,对其中一个对象的修改不会影响另一个。`clone`方法是Java `Object...

    JAVA创建对象的四种方法

    -java 创建对象的四种方法是指在 Java 中创建对象的不同方式,它们分别是使用 new 语句创建对象、使用反射机制创建对象、使用 clone() 方法创建对象和使用反序列化机制创建对象。 - 使用 new 语句创建对象是 Java ...

    Java面试指南.pdf

    - Java创建对象的方式:可以通过new关键字直接创建,也可以通过反射机制、clone方法或反序列化等方式创建。 - 序列化和反序列化:序列化是将对象的状态信息转换为可以存储或传输的形式的过程,反序列化则是把序列...

    Java Clone深拷贝与浅拷贝的两种实现方法

    深拷贝可以使用多种方法来实现,例如使用序列化和反序列化、使用复制构造函数、使用 clone() 方法等。 例如,我们可以使用下面的代码来实现深拷贝: ```java public class Student implements Cloneable { ...

    2023编程精选题库:Java面试题集及参考答案.docx

    Java 中创建对象的几种方式包括采用 new、通过反射、采用 clone、通过序列化机制等方式。 九、switch 语句 switch 语句可以使用 byte、short、char、int 或者其对应的封装类、Enum 类型和 String 类型。从 Java ...

    java List 深度复制方法

    以下是一个简单的深复制示例,使用了Java的序列化机制: ```java import java.io.*; public class DeepCopyExample { public static <T> List<T> deepCopy(List<T> originalList) throws IOException, ...

    Java面试小抄第一版 By 库森.pdf

    在《Java面试小抄第一版》中,作者库森详细整理了一系列Java编程语言和相关技术栈的面试知识点,这些知识点覆盖了Java基础、面向对象、异常处理、数据结构、集合框架、泛型、反射、序列化等多个方面,是Java开发者...

    笔试Java3.doc

    Java 编程中的多个基础知识点,涵盖了线程、同步、序列化、流、文件读写、Socket 通讯、SQL、 PrepardStatement、Java 反射机制、Eclipse 安装、Javadoc、匈牙利命名方式、事件监听模型、SQL 联接数据、JDK1.5 新...

    java深度克隆

    这种方法利用Java的序列化机制实现深度克隆。具体步骤如下: 1. **实现Serializable接口**:需要被克隆的类必须实现`Serializable`接口。 2. **序列化对象**:将对象转换为字节流。 3. **反序列化对象**:从字节流...

    java四种创建对象的方式

    Java中创建对象主要有四种显式的方式,分别是使用new关键字、反射机制、克隆克隆方法以及反序列化手段。每种方法都有其特定的使用场景和特点,以下是这些方法的详细说明: 1. 使用new关键字创建对象 这是最常见也是...

Global site tag (gtag.js) - Google Analytics