对象流
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。通俗来说就是将数据结构或对象转换成二进制串的过程。
ObjectOutputStream
writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。
eg:
public class Person implements Serializable{
private static final long serialVersionUID = 3851308503396805613L;
private String userName;
transient private String password;
private static String sex;
public Person(String userName,String password,String sex) {
this.userName = userName;
this.password = password;
this.sex = sex;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Person userName:"+userName +" password:"+password + " sex:"+sex;
}
public static String getSex() {
return sex;
}
public static void setSex(String sex) {
Person.sex = sex;
}
}
public class ObjectTest {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream(new File("d:/blog/object.tmp"));
ObjectOutputStream oos = new ObjectOutputStream(os);
Person p = new Person("testUser","test1234","man");
oos.writeObject(p);
oos.close();
os.close();
}
}
ObjectInputStream
readObject 方法用于从流读取对象。应该使用 Java 的安全强制转换来获取所需的类型。在 Java 中,字符串和数组都是对象,所以在序列化期间将其视为对象。读取时,需要将其强制转换为期望的类型。
eg:
InputStream is = new FileInputStream(new File("d:/blog/object.tmp"));
ObjectInputStream ois = new ObjectInputStream(is);
p.setUserName("testTest");
p.setSex("woman");
p = (Person)ois.readObject();
System.out.println(p.toString());
ois.close();
is.close();
总结
当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。一个静态变量不管是否被transient修饰,均不能被序列化。