存储的两种状态
序列化
纯文本文件
如果只有自己的Java程序用数据:序列化
可能被其他程序引用:纯文本文件
接口 Serializable来自 java.io.*;
创建FileOutputStream :这是连接文件的,较底层
FileOutputStream
fileStream
=
new
FileOutputStream(
"MyGame.ser"
);
创建ObjectOutputStream ;把对象层次转换串流级别记入FileOutputStream。
ObjectOutputStream
os =
new
ObjectOutputStream(fileStream);
调用方法写入对象
os.writeObject(
characterOne
);//也就是把变量引用的对象序列化并写入MyGamer.set文件
os.writeObject(
characterTwo
);
os.writeObject(
characterThree
);
关闭ObjectOutputStream
os.close();//关闭关联的输出串流-----------------------------
应该注意到,串流要两两连接才能有意义(
FileOutputStream和
ObjectOutputStream
),这其中一个表示连接,另一个调用方法。至于为什么是两个?连接的串流一般是很低层的。
FileOutputStream
有写入字节的方法。但我们一般不会直接写字节,而是以对
象层
次的观点来操作,所以需要高层连接串流
ObjectOutputStream与
FileOutputStream连接。
FileOutputStream把字节写入文件。
ObjectOutputStream把对象转换成可以写入串流的数据。调用writeObject时对象会被打成串流送入
FileOutputStream来写入文件。
另外值得注意的是以上语句可能会抛出异常所以应该放置在try{}里
同一个类的不同对象的区别的关键在于其实例变量的不同(那么当然你需要保存实例变量)。所以在对象被序列化时,被该对象引用的实例变量也会序列化,且引用的对象也会序列化,这些是自动进行的。
上述也提到一个问题是其引用的对象会一同序列化,是所以引用到的。
类可以被序列化需要实现接口 Serializable
这时也要注意到你需要在所有可能用到的类中实现参考上言。序列化的类要实现接口,其中引用到了其他对象那么也要实现。
如果实例变量不能或者不应序列化标记为 teansient(瞬时)这样会跳过它进行序列化
解序列化(Deserializtion):还原对象
创建FileInputStream连接文件
FileInputStream
fileStream
=
new
FileInputStream(
"MyGame.ser"
);
创建
ObjectInputStream
用来读取对象,但是需要链接
FileInputStream提供文件存取
ObjectInputStream os =
new
ObjectInputStream(fileStream);
读取对象
Object one = os.readObject();
Object two = os.readObject();
Object three = os.readObject();
转换对象类型(默认Object)
GameCharacter
elf = (
GameCharacter
) one;
GameCharacter
troll = (
GameCharacter
) one;
GameCharacter
magician = (
GameCharacter
) one;
关闭
ObjectInputStream
os.close();
解序列化时,
对象从stream中读出来,虚拟机会判断其class类型;
Jvm寻找其类并加载,如果找不到会抛出异常;
新对象被配置在堆上,但
注意新对象的构造方法不会执行
,因为构造方法会将对象恢复全新,我们想要的是对象的状态是此前储存的;
如果对象的继承树上某个祖先类不可序列化,则它在构造时的构造函数会执行,显然构造函数的递归性会连锁讲其以上的父类全部初始化;
被transient修饰的变量会被赋予默认值。