1、数据在串流中移动
串流要两两连接才好传输数据。一个表示连接(eg:FileOutputStream),一个要被调用方法(ObjectOutputStream)。
为什么使用两个:面向对象,每个类只要做好一件事。
2、序列化会将对象版图上的所有东西存储起来,被对象实例变量引用的所有对象都会被序列化。
3、实现serializable接口序列化:没有实现任何方法,声明这类是可以被序列化的
4、序列化的文件不可直接读取,是二进制流
//将序列化对象写入文件
//没有myFile.txt这个文件的话就会创建
//创建读取文件的fileoutputstream对象
FileOutputStream filestream = new FileOutputStream("myFile.txt");
//创建os对象,将对象打成串流送到FileOutputStream中保存
ObjectOutputStream os = new ObjectOutputStream(filestream);
//写入对象
os.writeObject(characterOne);
//关闭流
os.close();
5、要被序列化的对象,被该对象实例变量引用的所有对象都应该可以被序列化,否则会无法序列化该对象
6、对于不需要被序列化的被引用的对象,标记为transient(瞬时)类型的,序列化的时候会跳过它。
transient的对象会以null保存,或者基本数据类型默认值。
class Test implements Serializable {
//currentId 不会被序列化
transient String currentId;
String name;
}
7、解序列化Deserialization
//文件不存在会抛出异常,文件输入流知道如何链接文件
FileInputStream filestream = new FileInputStream("myFile.txt");
//os靠链接的文件流来读取对象
ObjectInputStream os = new ObjectInputStream(filestream);
//每次从流里面读取一个对象,读取顺序与写入顺序相同,次数超过会抛出异常
Object one = os.readObject();
//转换对象类型
CharacterGame elf = (CharacterGame)one;
//关闭流, FileInputStream会跟着关闭
os.close();
8、解序列化流程:
a.对象从stream读出来
b.Java虚拟机通过存储的信息判断对象的class类型
c.Java虚拟机尝试寻找和加载对象的类,找不到或无法加载会抛出例外
d.新对象被分配在堆上,构造方法不会执行,对象回到存储时的状态。如果执行构造方法,对象就变成新的了。
e.若对象继承树上有非序列化父类,则该父类和它之上的父类的构造函数就会执行。从第一个不可序列化的父类开始,全部都会重新初始状态。
f.对象的实例变量会还原成序列化时点的状态值。transient变量会变为null,或者基本数据类型的默认值。
9、静态变量不会被序列化,是 每个类一个。对象被还原时候,静态变量会维持类中原本的样子,不是存储时的样子。
10、通过序列化来存储对象状态
11、
public class MyClass {
public static void main(String[] args) {
saveData();
readData();
}
public static void saveData() {
TestBox one = new TestBox(1, "huahua");
TestBox two = new TestBox(2, "xiaoxiao");
TestBox three = new TestBox(3, "yuanyaun");
try {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.txt"));
outputStream.writeObject(one);
outputStream.writeObject(two);
outputStream.writeObject(three);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
one = null;
two = null;
three = null;
}
public static void readData() {
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("test.txt"));
TestBox onetest = (TestBox) inputStream.readObject();
TestBox twotest = (TestBox) inputStream.readObject();
TestBox threetest = (TestBox) inputStream.readObject();
System.out.println("one's age:" + onetest.age);
System.out.println("two's age:" + twotest.age);
System.out.println("three's age:" + threetest.age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TestBox implements Serializable {
int age;
String name;
public TestBox(int age, String name) {
this.age = age;
this.name = name;
}
}
12、区别于Parcelable,parcelable是安卓特有的序列化方式,serializable是Java的序列化方式。
parcelable适用于内存中传递数据,不适合网络和本地保存数据,因为不能保证数据的连续性。
serializable序列化的时候会产生大量的临时变量,引起频繁gc。