串行化是java.io包中的一部分,它被用来将对象转换成一串字节。在串行化的过程中,将一个实体转变成一系列表示对象的字节,这些字节可以写入文档以备后用,通过网络连接传输到其他程序,用来对初始对象进行拷贝等等。
如果你需要串行化一个类,那么就必须对这个类执行java.io.Serializable,并且提供一个无争议的构造器。Serializable接口不需要任何方法,因此你的这个类不再需要别的了。
如果你有一个简单的类似bean的类,而这个类仅仅是把原始的、可串行化对象作为属性,那么你就不需要再做别的了。当你需要将对象串行化为一系列字节或由一系列字节串行化而来时,Java可以负责所有的细节。
你可能会遇到的两个问题
串行化可能变得复杂得多。对于串行化,你通常会遇到两个常有的问题:类版本和复杂对象。
版本可能是你将碰到的第一个问题。譬如说,如果你在将实体串行化到一个磁盘之后,给你的类添加一种方法或属性,然后想将串行化实体存储回内存中,你将得到一个java.io.InvalidClassException。之所以会出现这个错误,是因为你的类的版本已经改变。这个问题可以得到解决,但是你必须花一些功夫。说得更详细一点就是检查Java对象串行化细节。
第二个可能的问题是,你的类是否有一些虚拟机不知道怎么串行化的状态信息。如果是那样,你可以通过以下两种方法来完成读写类的实例的任务。
private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
注意,这两种方法是私有的,串行化是特殊的。如果你想了解情况,就请看java.io.ObjectOutputStream和java.io.ObjectInputStream的源代码,并且一定要阅读关于java.io.Serializable的javadoc的内容。
以下是一个可以供你进行实验的完整串行化例子:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Random;
public class SerializableTipHelper { private static final String STORE_FILE = "bytes.out"; private static final boolean VERBOSE = true; public static void main(String[] args) { if ( args.length != 1 && args.length != 2 ) { System.out.println("use: SerializableTipHelper (read|write) [numberToWrite]"); return; } if ( args[0].equals("write") ) { try { write(Integer.parseInt(args[1])); } catch (IOException e) { e.printStackTrace(); } } // defaults to read else { try { read(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace();
} } }
public static void read() throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new FileInputStream(STORE_FILE)); int numRead = 0; Object o = null; try { while ( (o = in.readObject()) != null ) { numRead++; if ( VERBOSE ) { System.out.println("read " + numRead + ": " + o); } } } catch (EOFException e) { // suppress } }
public static void write(int num) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(STORE_FILE));
Random rand = new Random(System.currentTimeMillis());
for (int i = 0; i < num; i++) { SerializableTip st = new SerializableTip(); st.setAge(rand.nextInt(1000)); st.setEmployed(rand.nextBoolean()); st.setName("instance-" + i); Employee e = new Employee(); e.setId(rand.nextInt()); e.setName("employee-" + i); st.setEmployee(e); if ( VERBOSE ) { System.out.println("writing: " + st); } out.writeObject(st); } out.close(); } }
class SerializableTip implements Serializable { private String name; private int age; private boolean employed; private Employee employee; private int weight; public int getAge() { return age; } public String getName() {
return name; } public void setAge(int i) { age = i; } public void setName(String string) {
name = string; }
public boolean isEmployed() { return employed; } public void setEmployed(boolean b) { employed = b; } public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public String toString() { StringBuffer me = new StringBuffer(); me.append("[").append(super.toString()) .append(",name=").append(this.name) .append(",age=").append(this.age) .append(",employed=").append(this.employed) .append(",employee=").append(this.employee) .append("]"); return me.toString(); } public int getWeight() { return weight; } public void setWeight(int i) { weight = i; } }
class Employee implements Serializable { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public java.lang.String getName() { return name; } public void setName(java.lang.String name) { this.name = name; } public String toString() { StringBuffer me = new StringBuffer(); me.append("[").append(super.toString()) .append(",id=").append(this.id) .append(",name=").append(this.name) .append("]"); return me.toString(); } }
|