`

I/O 5:序列化

    博客分类:
  • I/O
 
阅读更多

 

一个类如想被序列化,是需要实现java.io.Seralizable接口,该接口中没有定义任何方法,是一个标识性接口(Marker Interface),当一个类实现了该接口,就表示这个类的对象是可以序列化的。

transient这个关键字只用在序列化中,将引用的对象标识为transient,则此对象不会被序列化。如下

private transient User ....

 

在序列化时,static变量是无法被序列化的;如果A包含了对B的引用,那么在序列化A时也会将B一并地序列化;如果此时A可以序列化,B无法序列化,那么当序列化A的时候就会发生异常。这时就需要将对B的引用设为transient。该关键字表示变量不会被序列化。

 

package com.test.io;

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

public class SerializableTest {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//序列化
		Person p1 = new Person(21,"zhangsan",1.61);
		Person p2 = new Person(23,"lisi",1.75);
		Person p3 = new Person(22,"hp",1.70);
		FileOutputStream fos = new FileOutputStream("person.txt");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(p1);
		oos.writeObject(p2);
		oos.writeObject(p3);
		oos.close(); //只需要关闭最外层
		
		System.out.println("--------------");
		//反序列化
		FileInputStream fis = new FileInputStream("person.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		Person p = null;
		for (int i = 0; i < 3; i++) {
			p = (Person) ois.readObject();
			System.out.println("name ="+p.name+" age = "+p.age+" height = "+p.height);
		}
		ois.close();
	}
}

class Person implements Serializable{
	int age;
	transient String name;  //transient定义的变量不会被序列化
	double height;
	public Person(int age,String name,double height) {
		this.age = age;
		this.name = name;
		this.height = height;
	}
}

 打印结果为

由于name是transient的,所以不会被序列化。

 

实现上述两个方法后,序列化与反序列化则完成类自身来控制。

 

package com.test.io;

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

public class SerializableTest2 {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//序列化
		Person2 p1 = new Person2(21,"zhangsan",1.61);
		Person2 p2 = new Person2(23,"lisi",1.75);
		Person2 p3 = new Person2(22,"hp",1.70);
		FileOutputStream fos = new FileOutputStream("Person2.txt");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(p1);
		oos.writeObject(p2);
		oos.writeObject(p3);
		oos.close(); //只需要关闭最外层
		
		System.out.println("--------------");
		//反序列化
		FileInputStream fis = new FileInputStream("Person2.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		Person2 p = null;
		for (int i = 0; i < 3; i++) {
			p = (Person2) ois.readObject();
			System.out.println("name ="+p.name+" age = "+p.age+" height = "+p.height);
		}
		ois.close();
	}
}

class Person2 implements Serializable{
	int age;
	transient String name;  //transient定义的变量不会被序列化
	double height;
	public Person2(int age,String name,double height) {
		this.age = age;
		this.name = name;
		this.height = height;
	}
	private void writeObject(ObjectOutputStream oos) throws IOException{
		System.out.println("write object");
		oos.writeInt(this.age);
		oos.writeUTF(this.name);
	}
	private void readObject(ObjectInputStream ois) throws IOException{
		System.out.println("read object");
		this.age = ois.readInt();
		this.name = ois.readUTF();
	}
	
}

 当我们在一个待序列化/反序列化的类中实现了上面两个private方法(方法声明要与上面的保持一致),那么就允许我们以更加底层,更加细粒度的方式序列化/反序列化的过程。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics