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-09-24 02:04:59

Serializable Clonable的相关文章

[Android]Parcelable encountered IOException writing serializable object (name = xxx)

Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short[].int.int[].long.long[].float.float[].double.double[].String.String[],还有实现Serializable.Parcelable接口的类对象. package com.example.test; import android.os.

java io学习(五) 序列化总结(Serializable 和 Externalizable)

本章,我们对序列化进行深入的学习和探讨.学习内容,包括序列化的作用.用途.用法,以及对实现序列化的2种方式Serializable和Externalizable的深入研究. 1. 序列化是的作用和用途 序列化,就是为了保存对象的状态:而与之对应的反序列化,则可以把保存的对象状态再读出来. 简言之:序列化/反序列化,是Java提供一种专门用于的保存/恢复对象状态的机制. 一般在以下几种情况下,我们可能会用到序列化: a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候: b)当你想用套接

Android中Intent使用Serializable和Parcelable传递对象

Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcelable(Key, Object);当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口,为了让大家更容易理解我还是照常写了一个简单的Demo,大家就一步一步跟我来吧! 第一步:新建一个Android工程命名为ObjectTranDemo(类比较

park serializable-Spark程序报错“Task not serializable”

问题描述 Spark程序报错"Task not serializable" 用java写的Spark程序在运行时报错"org.apache.spark.SparkException: Task not serializable",我在一个类里实现数据处理的功能,main函数定义在另一个类内部,在main函数中调用前一个类中的方法.虽然两个类都实现了Serilizable接口,但是还是无济于事.求大虾赐教!

Serializable与Parcelable传递对象详解(activity间传递对象方式)

先了解什么是序列化? 序列化是什么:  序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得.  序列化分为两大部分:序列化和反序列化.序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输.反序列化就是打开字节流并重构对象.对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据.恢复数据要求有恢复数据的对象实例  序列化的什么特点:  如果某个类能够被序列化,其子类也可以被序列化.声明为static和transient类型的成员数据不能被序列

Java IO--对象序列化Serializable、ObjectOutputStream、ObjectInputStream、transient

1.对象序列化是什么? 一个对象产生之后实际上是在内存中为其开辟了一个存储空间,方便存储信息. 定义可序列化的类: import java.io.Serializable ; public class Person implements Serializable{ private String name ; // 声明name属性,但是此属性不被序列化 private int age ; // 声明age属性 public Person(String name,int age){ // 通过构造

java-JAVA serializable 类 未声明类型为 long 的静态终态

问题描述 JAVA serializable 类 未声明类型为 long 的静态终态 新手,就是完全照书上码了一段,但怎么会有这些提示? ![ 图片说明](http://img.ask.csdn.net/upload/201502/18/1424249621_652792.png) 还有一张传不上去 这都是些什么问题?麻烦大致讲下 谢谢 代码如下 import java.awt.Container; import java.awt.FlowLayout; import java.awt.even

java序列化1[实现Serializable接口]

 * java默认序列化  * 1.实现Serializable接口(约定)  * 2.序列化和反序列化  * 3.实现java对象和字节序列的转换  * 4.将对象的字节序列(内存)持久化到磁盘(通常为文件),高并发session处理(减轻内存压力)  * 5.网络传输对象的字节序列,两个进程实现远程网络通信,(所有数据类型,都以二进制序列形式在网络上传送(接受发送))  * 6.实现Serializable接口的类采用默认的序列化方式 .* 7.静态变量(类变量)和transient修饰变量

java中实现Serializable接口的类有什么特点?

问题描述 java中实现Serializable接口的类有什么特点? java中实现Serializable接口的类有什么特点,还看到这个实现该接口的类里面一个常量,private static final long serialVersionUID = 1L;如何理解这个常量呢 解决方案 Serializable是一个标识接口,没有需要实现的方法,凡是实现该接口的类都可以进行序列化和反序列化操作. 实现serializable接口的作用是就是可以把对象存到字节流,然后可以恢复.所以你想如果你的