一、序列化:内存中的 Java 对象------->二进制流
二、目的:
a)把对象存储到外部存储器中持久化保存
b)通过网络传输对象。
三、可序列化的对象,Java 要求可序列化的类实现下面两个接口之一。
—Serializable:接口只是一个标记性的接口,实现该接口无需实现任何方法;
—Externalizable :实现该接口需要实现方法。
四、序列化的 IO 流:
ObjectInputStream —负责从二进制流“恢复”对象-->从文件中提取对象;
ObjectOutputStream —负责将内存中的对象写入磁盘
示例1:
public class Apple implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String color;
private int weight;
public Apple() {
super();
}
public Apple(String name, String color, int weight){
super();
this.name = name;
this.color = color;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Apple [name=" + name + ", color=" + color
+ ", weight="+ weight + "]";
}
}
测试:
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Apple apple=new Apple("紅富士","紅色",25);
ObjectOutputStream oos = new
ObjectOutputStream(new
FileOutputStream("f:/1.txt"));
oos.writeObject(apple);
ObjectInputStream ois = new
ObjectInputStream(new FileInputStream("f:/1.txt"));
System.out.println(ois.readObject());
oos.close();
ois.close();
}
}
五、引用变量的序列化机制:
A、引用变量所引用的对象的所有属性都应该是可序列化的。
B、如果要序列化的对象是之前已经序列化的,此时系统序列化一个编号。这种序列化机制,
就是为了保存磁盘里的二进制流与内存中的对象是对应的。
【注意】
A、 transient:用于修饰实例成员变量(不能与 static 修饰符同时使用)。 用于指定被修饰的
field 不会被序列化。好处:比如银行卡账号、密码就不应该被序列化出来。
B、由于 static 修饰的类变量存储在类信息中,并不存储在对象里,所以有 static 修饰的类变
量不能被序列化。
示例:自定义序列化类
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String account;
private String password;
public User() {}
public User(String account, String password) {
this.account = account;
this.password = password;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [account=" + account + ", password="+ password + "]";
}
// 下面两个方法,提供给系统调用,系统会调用者两个方法完成实际的序列化
private void writeObject(ObjectOutputStream out) throws IOException {
// 序列化User的两个属性
out.writeUTF(account);
out.writeUTF(new
StringBuilder(password).reverse().toString());
}
private void readObject(ObjectInputStream in)throws
IOException,ClassNotFoundException {
account = in.readUTF();
password = new
StringBuilder(in.readUTF()).reverse().toString();
}
}
测试:
public class Test {
public static void main(String[] args) {
User user = new User("张三", "123");
//将对象写入到文件中
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new
FileOutputStream("f:/1.txt"));
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
//从文件中读取对象
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new
FileInputStream("f:/1.txt"));
User u = (User) ois.readObject();
System.out.println(u.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}