`
henry406
  • 浏览: 115798 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用序列化实现对象深拷贝

    博客分类:
  • java
JVM 
阅读更多
实现树节点的深拷贝
    public DefaultMutableTreeNode deepCopy(DefaultMutableTreeNode node) {
        DefaultMutableTreeNode cloneNode = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(node);

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.
                    toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            cloneNode = (DefaultMutableTreeNode) ois.readObject();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
            Log.errorException(this, ex);
        } catch (IOException ex) {
            ex.printStackTrace();
            Log.errorException(this, ex);
        }

        return cloneNode;
    }



附一个序列化的例子:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//利用序列化来做深复制
//深clone
public class DeepCloneTest {

    public static Student deepCopy(Student node) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(node);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        Student cloneNode = (Student) ois.readObject();

        return cloneNode;
    }

    public static void main(String[] args) throws Exception {
        //teacher对象将不被clone出来的Student对象共享.
        Teacher teacher = new Teacher();
        teacher.setAge(40);
        teacher.setName("Teacher zhang");

        Student student1 = new Student();
        student1.setAge(20);
        student1.setName("zhangsan");
        student1.setTeacher(teacher);

        //复制出来一个对象student2
        Student student2 = (Student) student1.deepCopy();
//        Student student2 = deepCopy(student1);
        System.out.println(student2.getAge());
        System.out.println(student2.getName());

        System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println(student1.getTeacher().getAge());
        System.out.println(student1.getTeacher().getName());

        //修改student2的引用对象
        student2.setName("ddddddddd");
        student2.getTeacher().setAge(50);
        student2.getTeacher().setName("Teacher Li");

        System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println(student1.getAge());
        System.out.println(student1.getName());
        System.out.println(student1.getTeacher().getAge());
        System.out.println(student1.getTeacher().getName());
    }
}


class Teacher implements Serializable {

    private static final long serialVersionUID = -8834559347461591191L;

    public int age;
    public String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


class Student implements Serializable, Cloneable {

    //serialVersionUID 如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。
    //但当serialVersionUID相同时,它就会将不一样的field以type的缺省值赋值(如int型的是0,String型的是null等),这个可以避开不兼容性的问题。所以最好给serialVersionUID赋值
    private static final long serialVersionUID = 7991552226614088458L;

    public int age;
    public String name;
    public Teacher teacher;
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    //序列化实现深拷贝
    public Object deepCopy() throws Exception {
        //将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(this);

        //将流序列化成对象
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

        ObjectInputStream ois = new ObjectInputStream(bis);

        return ois.readObject();
    }

    //浅拷贝
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    C#基于表达式(Expression)实现对象深拷贝

    总的来说,通过C#的表达式树实现对象深拷贝提供了一种灵活且高效的方式,尤其适用于那些需要高性能和深度定制拷贝逻辑的场景。但是,也需要根据实际需求权衡其复杂性和适用性。在学习和使用过程中,可以结合提供的`...

    java 对象的序列化与反序列化

    5. **深拷贝与浅拷贝**:序列化实际上是实现了深拷贝,即创建了对象的一个完全独立的副本,修改副本不会影响原对象。 6. **安全性问题**:序列化可能导致安全漏洞,因为恶意用户可以通过反序列化执行任意代码。因此...

    java对象序列化 传输 保存

    6. **深拷贝与浅拷贝**:在序列化过程中,对象的引用会被复制,可能导致浅拷贝。如果需要完全独立的副本(深拷贝),则需要额外处理。 7. **自定义序列化和反序列化**:通过实现`writeObject()`和`readObject()`方法...

    winform 深拷贝的实现源码

    本资源提供的“winform 深拷贝的实现源码”应该是一个针对WinForm应用中对象深拷贝的具体实现示例。 首先,我们来理解一下浅拷贝和深拷贝的概念: 1. **浅拷贝**:浅拷贝只是创建了一个新对象,该对象拥有原始对象...

    C#浅拷贝(MemberwiseClone等多种方法)与深拷贝(反射、多种反序列化)实例

    在C#中,可以使用几种不同的方法来实现深拷贝,如手动实现、序列化/反序列化、反射等。 1. 手动实现:针对每个类,编写复制所有字段的构造函数或方法。 2. 序列化/反序列化:利用`BinaryFormatter`或`XmlSerializer...

    详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)

    `TestString`类中的`main`方法展示了浅拷贝、默认`clone()`方法实现的深拷贝以及序列化实现的深拷贝的用法。`qianCopyTest()`展示了浅拷贝的效果,其中对于包含可变对象的`Person`实例,修改副本会影响原始对象。`...

    Java中的深拷贝(深复制)和浅拷贝(浅复制) 示例代码

    深拷贝可以通过序列化和反序列化实现,或者手动实现Cloneable接口并重写`clone()`方法。 示例代码(使用序列化): ```java import java.io.*; class MyClass implements Serializable { int a; String b; ...

    序列化(Serialization)实现深拷贝.md

    深拷贝:指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含多层...这时我们可以用序列化来实现对象的深拷贝。

    Java实现序列化例子

    4. **序列化与深拷贝**:序列化也可以用于实现深拷贝,即创建一个与原始对象具有相同数据的新对象,但它们在内存中是独立的。 5. **优化序列化**:有时,对象可能包含大量数据,或者有复杂的引用结构,这可能导致...

    使用java反射机制实现java的深拷贝

    总结来说,Java反射机制为我们提供了动态访问和操作类的能力,可以用来实现对象的深拷贝。然而,反射使用时应谨慎,因为它可能导致性能下降,且容易引入安全隐患。在设计类时,优先考虑使用序列化、克隆或自定义拷贝...

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

    首先,要使用序列化实现对象克隆,对象必须实现`Serializable`接口。这是一个标记接口,没有定义任何方法,但它的存在表明这个类的对象可以被序列化。例如: ```java public class MyClass implements Serializable...

    ios-深拷贝对象.zip

    KNArchiveModel是一个常用的第三方库,它提供了一种简单的方式来序列化和反序列化Objective-C或Swift对象,包括深拷贝功能。使用这个库,开发者可以轻松地将对象转化为字节流(存储到磁盘或网络传输),然后在需要时...

    C#中序列化实现深拷贝,实现DataGridView初始化刷新的方法

    此时,可以利用序列化实现深拷贝的方法来达到这一目的。本文将详细介绍如何通过序列化实现深拷贝以及如何实现`DataGridView`的初始化刷新。 首先,深拷贝是指创建一个对象的新副本,这个副本与原对象完全相同,包括...

    深拷贝浅拷贝.zip

    以下是通过序列化和反序列化实现深拷贝的例子: ```csharp using System.IO; using System.Runtime.Serialization.Formatters.Binary; // 序列化实现深拷贝 MyClass deepCopy = null; using (var ms = new ...

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

    为了实现 Java 序列化,需要将需要被序列化的类实现 Serializable 接口,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 ...

    C#中的浅拷贝和深拷贝

    然后,将当前对象序列化到 `MemoryStream` 中,接着重新定位到流的起始位置,最后从流中反序列化出一个新的对象,从而实现了深拷贝的效果。 总结来说,浅拷贝和深拷贝在不同的应用场景下有着不同的作用。浅拷贝通常...

    用序列化实现ListT 实例的深复制(推荐)

    以下是如何使用序列化实现List实例深复制的步骤: 1. 首先,创建一个辅助类`SerializLog`,该类包含一个静态方法`Clone<T>`,它接受一个泛型参数T,代表要复制的对象类型。 2. 在`Clone<T>`方法中,我们创建一个`...

    浅谈Java中实现深拷贝的两种方式—clone() & Serialized

    但是,Serialized方法需要对象实现Serializable接口,并且可能会出现序列化和反序列化的错误。 Java中实现深拷贝的两种方式—clone()和Serialized—are two effective methods to achieve deep copying in Java. By...

    C#浅拷贝深拷贝

    在C#中,实现深拷贝通常需要自定义序列化和反序列化过程,或者手动复制每个成员。 比如,我们可以这样实现一个深拷贝: ```csharp public class MyClass : ICloneable { public string Str; public object ...

    Java实现实体类拷贝[深,很深的那种...]

    - **序列化和反序列化**:如果实体类实现了`Serializable`接口,可以利用`ObjectOutputStream`和`ObjectInputStream`进行序列化和反序列化实现深拷贝。这种方式的优点是简单,但缺点是效率较低,且所有属性都需要...

Global site tag (gtag.js) - Google Analytics