Serializable Clonable

简介: 序列化机制有一种很有趣的用法:可以方便的克隆对象,只要对应的类是可序列化的即可。操作流程:直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对现有对象的一个深拷贝(deep copy)。在此过程中,不需要将对象写出到文件中,因为可以用ByteArrayOutputStream将数据保存到字节数组中;tips:方法的确很灵巧,但通常会比显式地构建新对象并复制或克隆数据域的克隆方法慢得多。

序列化机制有一种很有趣的用法:
可以方便的克隆对象,只要对应的类是可序列化的即可。
操作流程:
直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对现有对象的一个深拷贝(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]

 

相关文章
|
3月前
|
存储 Java
|
6月前
|
存储 JSON NoSQL
关于 Serializable的探讨
本文探讨了Java中的Serializable接口和serialVersionUID字段。Serializable是用于对象序列化的标记接口,用于持久化、传输或缓存对象状态。serialVersionUID是一个版本控制标识,确保反序列化时类版本兼容。它主要适用于Java内置序列化,不涉及JSON等其他序列化方式。作者还分享了一个在项目中考虑使用CountMinSketch数据结构但最终选择其他方法的例子,并建议在非必要情况下,DTO和VO对象可以不实现Serializable。
|
存储 Java
Serializable接口的意义和用法
Serializable接口的意义和用法
|
存储 JSON Java
浅谈项目中遇到的Serializable和Parcelable
安卓项目终于要到调用网络接口的时候了,之前了解到,需要对Java对象进行序列化操作,以json格式传入;接收的也是json并解析成Java对象。
114 0
|
存储 Java Android开发
Parcelable与Serializable
跟大家分享一下Android的序列化
105 0
|
存储 缓存 算法
HttpServlet为什么要实现serializable?
HttpServlet为什么要实现serializable?
123 0
HttpServlet为什么要实现serializable?
|
存储 Java
【Java】Serializable序列化
Serializable序列化“持久化”意味着对象的“生存时间”并不取决于程序是否正在执行——它存在或“生存”于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时重新恢复那个对象,就能圆满实现一种“持久”效果。
160 0
|
算法 Java 安全
Serializable原理
序列化是将对象变为可传输内容的过程, 反序列化则是将可传输内容转化为对象的过程. Java原生序列化方式是通过实现Serializable接口实现的. 不实现该接口会导致无法序列化, 抛出异常如下: java.io.NotSerializableException 序列化的应用场景: 将对象转换为字节流, 用于网络传输, 例如用于RPC远程调用。
5080 0
|
Android开发 Java 存储
序列化Parcelable和Serializable的区别
Parcelable和Serializable有什么用,它们有什么差别? Parcelable和Serializable都可以实现序列化,使对象可以变为二进制流在内存中传输数据。
3148 0