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

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

2016-05-01 15:54 501 查看

序列化与反序列化

序列化就是将对象的状态信息转换为可以存的字节序列存等储,在以后将这个字节序列恢复成对象就是反序列化。


实现Serializable的方式

public class Fruit implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

private String name;

private int size;

/**
* @param name
* @param size
*/
public Fruit(String name, int size) {
super();
this.name = name;
this.size = size;
}

public String getName() {
return name;
}

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

public int getSize() {
return size;
}

public void setSize(int size) {
this.size = size;
}

@Override
public String toString() {
return "Fruit [name=" + name + ", size=" + size + "]";
}

}


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

Fruit fruit = new Fruit("banana", 100);

ByteArrayOutputStream out = new ByteArrayOutputStream();

ObjectOutputStream stream = new ObjectOutputStream(out);

stream.writeObject(fruit);

ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));

Fruit fruitRecover = (Fruit) in.readObject();

System.out.println(fruitRecover);
}


输出:

Fruit [name=banana, size=100]

上面的例子中可以自定义读和写方法,如果有则调用自己的方法在Fruit中加入

private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException {
in.defaultReadObject();

//可以用自己的逻辑读数据
System.out.println("readObject");
}

private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();

//可以用自己的逻辑写数据
System.out.println("writeObject");

}


注意点

尽量在需要序列化的类中定义序列serialVersionUID ,否则虚拟机将自动调用方法实现一个序列,影响性能。

transient关键字的字段无法实现序列。

静态成员属于类级别的,所以不能序列化,除非你都在同一个机器(而且是同一个进程),且jvm已经把字段加载进来了。

实现Externalizable的方式

这种方法必须要自己实现读和写,并且必须要有无参数构造器,看下代码

public class Person implements Externalizable {

private String name;

private int age;

public Person() {
super();
System.out.println("default constructor");
}

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("params constructor");
}

public String getName() {
return name;
}

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

public int getAge() {
return age;
}

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

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

System.out.println("writeExternal");
}

@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
name = (String) in.readObject();
age = in.readInt();
System.out.println("readExternal");
}

}


public static void testES() throws IOException, ClassNotFoundException {
Person person = new Person("zzh", 20);

ByteArrayOutputStream out = new ByteArrayOutputStream();

ObjectOutputStream stream = new ObjectOutputStream(out);

stream.writeObject(person);

ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));

Person p = (Person) in.readObject();
System.out.println(p.getAge());
}


输出:

params constructor

writeExternal

default constructor

readExternal

20

一些使用场景

在一些网络传输、RMI等远程传输。

tomcat在重启时,也会将session中的对象序列化,我们不需要重新登录。

使用jrdis保存对象时也能用到。

参考

《Java编程思想》

http://www.hollischuang.com/archives/1150
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 序列化