对象的序列化:将对象转换为字节序列
对象的反序列化:将字节序列还原(恢复)成对象
序列化的优点:
1.可以将对象通过序列化保存到本地磁盘,起到方便存储的作用
2.可以通过对象序列化在网络之间进行传输,起到数据共享的作用
实现步骤:
前提:如果一个类要完成对象的序列化,该类必须实现Serializable接口(标示性接口)
1.将要实现对象序列化的类实现Serializable接口
2.使用对象流ObjectInputStream/ObjectOutputStream完成对象的序列化或反序列化
ObjectOutputStream类:继承了OutputStream类
构造函数:
ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。
常用方法:
writeObject(Object obj):将指定的对象写入 ObjectOutputStream。
writeXxx(Xx x):Xxx对应的是基本数据类型:写入一个 xx 值。
writeBoolean(boolean b) writeInt(int int) writeDouble(Double d)....
flush():刷新该流的缓冲。
close():关闭流。
ObjectInputStream类:继承了InputStream类
构造函数:
ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
常用的方法:
readObject() : 从 ObjectInputStream 读取对象。
readXxx():读取一个 xx 值。
readInt() readDouble()....
close(): 关闭输入流。
public class Student implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private double score; public Student() { } public Student(String name, int age, double score) { super(); this.name = name; this.age = age; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } }
public class TestObjectStream { public static void main(String[] args) { Student stu = new Student("zhangsan",20,80); File file = new File("D:/test.obj"); try { //1.对象序列化 OutputStream ops = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(ops); oos.writeObject(stu);//将stu对象写入指定位置 (序列化) oos.writeDouble(3.14);//将stu对象写入指定位置 (序列化) oos.flush(); //2.反序列化 InputStream ips = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(ips); Student stu2 = (Student)ois.readObject(); double pi = ois.readDouble(); System.out.println(stu2.getName()+"---"+stu2.getAge()+"---"+stu2.getScore()); System.out.println("pi="+pi); //关闭资源 oos.close(); ops.close(); ois.close(); ips.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
只能保存对象的非静态成员变量
不能保存任何成员方法和静态的成员变量
不保存transient成员变量
如果一个对象的成员变量是一个对象,这个对象的成员变量也会保存
public class Dept implements Serializable{ private int deptId; private String deptName; public Dept(){ } public Dept(int deptId,String deptName){ this.deptId= deptId; this.deptName=deptName; } public int getDeptId() { return deptId; } public void setDeptId(int deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
public class Employee implements Serializable{ private int empId; private String empName; private transient int empAge; //使用transient修饰的属性,该属性不能被序列化 private Dept dept;//封装了该员工对于的部门信息 public Employee() { } public Employee(int empId, String empName, int empAge, Dept dept) { this.empId = empId; this.empName = empName; this.empAge = empAge; this.dept = dept; } public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getEmpAge() { return empAge; } public void setEmpAge(int empAge) { this.empAge = empAge; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
public class TestObjectStream2 { public static void main(String[] args) { Dept dept = new Dept(1,"讨账部"); Employee employee = new Employee(1,"陈浩南",28,dept); Employee employee2 = new Employee(2,"山鸡",27,dept); try { //序列化 FileOutputStream fos = new FileOutputStream("tt.o"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(employee); oos.writeObject(employee2); //反序列化 FileInputStream fis = new FileInputStream("tt.o"); ObjectInputStream ois =new ObjectInputStream(fis); Employee emp = (Employee)ois.readObject(); System.out.println(emp.getEmpId()+"--"+emp.getEmpName()+"--"+emp.getEmpAge()); Dept dept2 = emp.getDept(); System.out.println(dept2.getDeptId()+"--"+dept2.getDeptName()); Employee emp2 = (Employee)ois.readObject(); System.out.println(emp2.getEmpId()+"--"+emp2.getEmpName()+"--"+emp2.getEmpAge()); Dept dept3 = emp2.getDept(); System.out.println(dept3.getDeptId()+"--"+dept3.getDeptName()); //关闭流 oos.close(); fos.close(); ois.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
public class User implements Serializable{ private String name; private int age; private Gender gender; public User(){ } public User(String name, int age, Gender gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } } //枚举 enum Gender{ 男,女 }
public class TestObjectStream3 { public static void main(String[] args) { List<User> list = new ArrayList<User>(); User user1 = new User("zhangsan",30,Gender.男); User user2 = new User("zhangsan2",24,Gender.男); User user3 = new User("zhangsan3",28,Gender.男); list.add(user1); list.add(user2); list.add(user3); try { // 序列化 FileOutputStream fos = new FileOutputStream("D:/tt.o"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(list); oos.flush(); //反序列化 FileInputStream fis = new FileInputStream("D:/tt.o"); ObjectInputStream ois = new ObjectInputStream(fis); List<User> usersList = (List)ois.readObject(); for (User user : usersList) { System.out.println(user); } ois.close(); fis.close(); oos.close(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }