您的位置:首页 > 编程语言 > Java开发

JAVA自定义序列化的神奇方法

2015-11-04 16:23 477 查看
大家都知道通过实现Externalizable接口,来自定义序列化,其实也不一定,首先我们来看一下怎么通过Externalizable来实现自定义序列化以及要注意的事情。

package com.liran.main.Stream;

import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

/**
* 通过实现Externalizable接口 进行自定义序列化
* 通过这种方式来实现序列化那么被序列化的类的构造函数必须是public的,不然会出现恢复异常
* 恢复对象的时候会调用默认的构造函数这一点和普通的序列化差别很大
* 如果没有默认的构造函数那么在恢复的时候就会出现java.io.InvalidClassException异常
* Created by liran on 2015-10-17.
*/
public class customSerizal {

public static void main(String[] args) throws IOException, ClassNotFoundException {

ObjectOutput out=new ObjectOutputStream(new FileOutputStream("data.out"));
Persons persons1=new Persons("你好a",18);
Persons persons2=new Persons("你好b",19);
out.writeObject(persons1);
out.writeObject(persons2);
out.close();

System.out.println("-------------------下面是从序列化中恢复-------------------------------");

ObjectInput in=new ObjectInputStream(new FileInputStream("data.out"));
Persons inpersons= (Persons) in.readObject();
Persons inpersons2= (Persons) in.readObject();
System.out.println(inpersons);
System.out.println(inpersons2);
in.close();
}
}

class Persons implements Externalizable {
private String name;
private int age;

public Persons() {
System.out.println("Persons 默认的构造函数");
}

public Persons(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Persons 非默认的构造函数 name is "+name+" age is "+age);
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(new StringBuffer(name).reverse());
out.writeInt(age);
}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.name = ((StringBuffer) in.readObject()).reverse().toString();
this.age = in.readInt();
}

@Override
public String toString() {
return "persion name is "+name+" age is "+age;
}
}


运行结果:

Persons 非默认的构造函数 name is 你好a age is 18
Persons 非默认的构造函数 name is 你好b age is 19
-------------------下面是从序列化中恢复-------------------------------
Persons 默认的构造函数
Persons 默认的构造函数
persion name is 你好a age is 18
persion name is 你好b age is 19

Process finished with exit code 0


其实通过实现
Serializable
接口也可以实现自定义序列化,就是在实现了这个接口的类中定义writeObject和readObject方法,必须严格按照我的范例中的格式, 然后ObjectOutputStream的writeObject方法和ObjectInputStream的readObject会检查这个Serializable 是否有自己的方法,如果有就调用它自己的。

下面来看代码:

package com.liran.main.Stream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
* 这里测试了一个很神奇的方法,就是通过implements Serializable也可以自定义序列化,
* 就是在实现了这个接口的类中定义writeObject和readObject方法,必须严格按照我的范例中的格式,
* 然后ObjectOutputStream的writeObject方法和ObjectInputStream的readObject会检查这个Serializable
* 是否有自己的方法,如果有就调用它自己的。
* Created by LiRan on 2015-11-04.
*/
public class SerializableReplaceTest {

public static void main(String[] args) throws IOException ,ClassNotFoundException{

Pig pig=new Pig(1,2);
ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream("data.txt"));
outputStream.writeObject(pig);
outputStream.close();

ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("data.txt"));
Pig pig1= (Pig) objectInputStream.readObject();
System.out.println(pig1);
objectInputStream.close();
}

}

class Pig implements Serializable{
int weight;
int heigh;

private void writeObject(ObjectOutputStream stream) throws IOException,ClassNotFoundException{
stream.defaultWriteObject();//这里为了省事直接调用了默认的序列化方法,当然也可以自己实现这个方法
System.out.println("自定义的writeObject");
}

private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException{
stream.defaultReadObject();//这里为了省事直接调用了默认的序列化方法,当然也可以自己实现这个方法
System.out.println("自定义的readObject");
}

public Pig() {
System.out.println("Pig的默认构造函数");
}

public Pig(int weight, int heigh) {
this.weight = weight;
this.heigh = heigh;
}

@Override
public String toString() {
return "pig weight is "+weight+" heigh is "+heigh;
}
}


运行结果:

自定义的writeObject
自定义的readObject
pig weight is 1 heigh is 2


这种方法是不是很神奇?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 序列化