/** * */ package iostream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * * 对象的序列化(Serializable): * * 当你创建对象的时候,只要你需要它,它就会一直存在。但是当程序终止的时候,无论如何都不会在继续存在。 * 尽管这么做是有意义的,但是我们仍然希望有时候呢能够在程序不运行的情况下仍然能够保存对象信息。 * * 对象序列化的概念加入到Java语言中有两个原因: * 1 Java的远程方法调用(RMI),它使得存活在其他计算机上面的对象看起来像是 * 存活于本机上一样; * 2 对于Java Bean来说,对象的序列化是必须的,使用一个Bean时,一般是在 * 设计阶段对它的状态信息进行配置,然后将这种状态信息保存下来,在程序启动 * 的时候恢复。 */ /** * 只需要实现Serializable接口(仅是一个标记接口,不包含 * 任何方法),对象的序列化处理就会非常简单。 * */ class Color implements Serializable{ String name; public Color(String name, int r, int g, int b){ System.out.print("Color Constructor\n"); this.name = name; this.r = r; this.g = g; this.b = b; } int r; int g; int b; } /** * 存储Orange的时候不仅仅是指存储该对象的“全景图”,而是会 * 追踪该对象中包含的所有引用,并保存那些对象。 * */ class Orange implements Serializable{ private String from; //即使是private,也会被序列化 private static int size = 0; //不是说static域不能被序列化么,为什么这里被序列化了??? transient int weight; //要想不被序列化,就标记成transient private Color color; //包含一个Color对象 public Orange(String from, int size, int weight, Color color){ System.out.print("Orange Constructor\n"); this.from = from; this.size = size; this.color = color; this.weight = weight; } public int getSize(){ return size; } public String toString(){ return "Color: "+color.name+","+color.r+","+color.g+"," + ""+color.b+", From: "+from+", Weight: "+weight+", Size: "+size; } } /** * 测试对象的序列化 * */ public class ObjectSerializationTest { /** * 存储一个Orange对象到文件 * */ public void testStoreObject(String file) throws IOException{ Orange o = new Orange("NanJing", 10, 20, new Color("green", 11,130,77)); System.out.println("Before serialize:"+o); //新建一个文件 File f = new File(file); f.createNewFile(); f.deleteOnExit(); //使用过滤器ObjectOutputStream将对象存入文件 ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file)); os.writeObject(o); os.close(); } /** * 注意 * (1) 如果这个恢复对象的代码写在另外一个路径下,而这个路径下面找不到Orange类, * 即Orange.class文件不在这个路径下(Orange.class在iostream下)。那么恢复这个对象 * 的时候会发生ClassNotFoundException。因为打开和读取存储的Orange对象中的内容 * 的时候需要用到Orange.class文件中的类信息。 * (2) 恢复Orange对象的时候,其构造器不会被调用。这个过程是通过从InputStream中 * 取得数据完成的。同时需要根据class文件才能完成。 * */ public void testReadObject(String file) throws FileNotFoundException, IOException, ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException{ //通过过滤器ObjectInputStream从文件流输入流中读取一个对象 ObjectInputStream oi = new ObjectInputStream(new FileInputStream(file)); Orange o = (Orange)oi.readObject(); oi.close(); System.out.println("After serialize"+o); } /** * @param args */ public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub ObjectSerializationTest ost = new ObjectSerializationTest(); String storeFile = "./testDir/object.txt"; String restoreFile = "./testDir/object.txt"; System.out.print("\n-------------- 向文件中存入一个对象 --------------\n"); ost.testStoreObject(storeFile); System.out.print("\n-------------- 从文件中恢复一个对象 --------------\n"); ost.testReadObject(restoreFile); } }