Serializable Clonable

序列化机制有一种很有趣的用法:
可以方便的克隆对象,只要对应的类是可序列化的即可。
操作流程:
直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对现有对象的一个深拷贝(deep copy)。在此过程中,不需要将对象写出到文件中,因为可以用ByteArrayOutputStream将数据保存到字节数组中;

tips:
方法的确很灵巧,但通常会比显式地构建新对象并复制或克隆数据域的克隆方法慢得多。

package io.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.GregorianCalendar;

/*2015-7-10*/
public class SerialCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Employee harry = new Employee("Harry Hacker", 60000, 1987, 1, 20);
        Employee harryClone = (Employee) harry.clone();
        System.out.println(harry.equals(harryClone));

        harry.raiseSalary(20);

        System.out.println(harry);
        System.out.println(harryClone);

    }

}

class SerialCloneable implements Cloneable, Serializable {
    private static final long serialVersionUID = 2439604536150013106L;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bout);
            out.writeObject(this);
            out.close();

            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream in = new ObjectInputStream(bin);
            Object ret = in.readObject();
            in.close();
            return ret;

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return super.clone();
    }
}

class Employee extends SerialCloneable {
    private static final long serialVersionUID = -167978670073609475L;
    private String name;
    private double salary;
    private Date hireDay;

    public Employee(String name, double salary, int year, int month, int dayOfMonth) {
        super();
        this.name = name;
        this.salary = salary;
        GregorianCalendar calendar = new GregorianCalendar(year, month - 1, dayOfMonth);
        this.hireDay = calendar.getTime();
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public Date getHireDay() {
        return hireDay;
    }

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }

    @Override
    public String toString() {
        return getClass().getName() + " [name=" + name + ", salary=" + salary + ", hireDay=" + hireDay + "]";
    }

}

Output:

false
io.clone.Employee [name=Harry Hacker, salary=72000.0, hireDay=Tue Jan 20 00:00:00 CST 1987]
io.clone.Employee [name=Harry Hacker, salary=60000.0, hireDay=Tue Jan 20 00:00:00 CST 1987]
时间: 2024-10-15 04:52:30

Serializable Clonable的相关文章

Java中的Serializable接口的作用

转载自:http://blog.csdn.net/shehun11/article/details/40300439 所谓的Serializable,就是java提供的通用数据保存和读取的接口.至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后了.这样子,任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方.也可以用管道来传输到系统的其他程序中.这样子极大的简化了类的设计.只要设计一个保存一个读取功能就能解决上面说得所有问题. Obj

序列化与反序列化总结(Serializable和Parcelable)

序列化是指将对象的状态信息转换为可以存储或传输的形式的过程. 在Java中创建的对象,只要没有被回收就可以被复用,但是,创建的这些对象都是存在于JVM的堆内存中,JVM处于运行状态时候,这些对象可以复用, 但是一旦JVM停止,这些对象的状态也就丢失了. 在实际生活中,需要将对象持久化,需要的时候再重新读取出来,通过对象序列化,可以将对象的状态保存为字节数组,需要的时候再将字节数组反序列化为对象. 对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间转换,广泛用于RMI(远程方法调用)以

面试题:Java中对象序列化接口(Serializable)的意义

Serializable接口是一个里面什么都没有的接口 它的源代码是public interface Serializable{},即什么都没有. 如果一个接口里面什么内容都没有,那么这个接口是一个标识接口,比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序

Android Serializable与Parcelable原理与区别

一.序列化.反序列化是什么? (1) 名词解释 对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程.对象的反序列化:把字节序列恢复为Java对象的过程. (2) 序列化详细解释 对象的序列化涉及三个点关键点:Java对象.字节序列.存储. 1. Java对象的组成?Java对象包含变量与方法.但是序列与反序列化仅处理Java变量而不处理方法,序列与反序列化仅对数据进行处理. 2. 什么是字符序列?字符序列是两个词,字符是在计算机和电信领域中,字符(Character)是一个

Android中Serializable和Parcelable序列化对象详解

学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.Parcelable的工作原理 6.相关实例 1.序列化的目的 (1).永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中 (2).通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式) (3).将对象数据在进程

Java 序列化Serializable

1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.   2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个

[Serializable]的应用--注册码的生成,加密和验证

1.首先定义注册类RegisterEntity [Serializable] public class RegisterEntity { public string RegisterKey; public bool IsRegistered; public List<int> RegisterOrder; public DateTime RegisterDate; public DateTime ExpireDate; } RegisterKey,注册码(序列号) IsRegistered,是

JDK1.8 java.io.Serializable接口详解

java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法.只是用于标识此接口的实现类可以被序列化与反序列化.但是它的奥秘并非像它表现的这样简单.现在从以下几个问题入手来考虑. 希望对象的某些属性不参与序列化应该怎么处理? 对象序列化之后,如果类的属性发生了增减那么反序列化时会有什么影响呢? 如果父类没有实现java.io.Serializable接口,子类实现了此接口,那么父类中的属性能被序列化吗? serialVersionUID属性是做什么用的?必须申明

Serializable unordered set

Serializable unordered set 可序列化的哈希表 /*''' [[[[[[[[[[[[[[[ ]]]]]]]]]]]]]]] [:::::::::::::: ::::::::::::::] [:::::::::::::: ::::::::::::::] [::::::[[[[[[[: :]]]]]]]::::::] [:::::[ ]:::::] [:::::[ ]:::::] [:::::[ ]:::::] [:::::[ Serializable unordered s