java进阶(35)--对象流、序列化与反序列化
Mrwhite86 人气:0文档目录:
一、基础概念
二、举例-序列化对象
三、举例-反序列化对象
四、举例-序列化与反序列化多个对象与
五、transient关键字
六、序列化版本号
---------------------------------------分割线:正文--------------------------------------------------------
一、基础概念
1、序列化:
关键词为Serialize,Java对象的状态保存下来的过程
2、反序列化:
关键词为DeSerialize,将硬件上的数据重新恢复到内存当中,恢复成Java对象
3、Serializable接口
参与序列化与反序列化的对象必须实现Serializable接口
参与序列化的集合元素都要实现Serializable接口,Serializable为一种标志接口
4、序列化版本号
Serializable是给Java虚拟机看的,会加载该类自动生成一个序列化版本号
二、举例-序列化对象
1、创建实现Serializable的student类
1 package JAVAADVANCE; 2 import java.io.Serializable; 3 public class Student02 implements Serializable { 4 private int no; 5 private String name; 6 public Student02() { 7 } 8 public Student02(int no, String name) { 9 this.no = no; 10 this.name = name; 11 } 12 public int getNo() { 13 return no; 14 } 15 public void setNo(int no) { 16 this.no = no; 17 } 18 public String getName() { 19 return name; 20 } 21 public void setName(String name) { 22 this.name = name; 23 } 24 }
2、创建TestAdvance35TestObjectOutputStreamTest01类实现序列化对象
1 package JAVAADVANCE; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 import java.io.ObjectOutputStream; 5 public class TestAdvance35TestObjectOutputStreamTest01 { 6 public static void main(String[] args) throws IOException { 7 //创建java对象 8 Student02 s=new Student02(1111,"zhangsan"); 9 //创建流 10 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("students")); 11 //序列化java对象 12 oos.writeObject(s); 13 //刷新 14 oos.flush(); 15 //关闭 16 oos.close(); 17 } 18 19 }
项目文件目录下生成Students文件,存储java对象,无法直接读取,需要反序列化读取
三、举例-反序列化对象
1 package JAVAADVANCE; 2 import java.io.*; 3 public class TestAdvance35TestObjectInputStreamTest01 { 4 public static void main(String[] args) throws IOException, ClassNotFoundException { 5 //创建流 6 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("students")); 7 //开始反序列化 8 Object obj=ois.readObject(); 9 //反序列化回来的是一个student02对象,所有会调用student02对象的toString方法 10 System.out.println(obj); 11 ois.close(); 12 } 13 }
查看运行结果:
Student02{no=1111, name='zhangsan'}
四、举例-序列化与反序列化多个对象
1、创建User类实现Serializable接口
1 import java.io.Serializable; 2 3 public class User implements Serializable { 4 private String name; 5 private int no; 6 7 public User() { 8 } 9 10 public User(String name, int no) { 11 this.name = name; 12 this.no = no; 13 } 14 15 @Override 16 public String toString() { 17 return "User{" + 18 "name='" + name + '\'' + 19 ", no=" + no + 20 '}'; 21 } 22 }
2、序列化多个对象
1 package JAVAADVANCE; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.ObjectOutputStream; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 public class TestAdvance35TestObjectOutputStreamTest02 { 10 public static void main(String[] args) throws IOException { 11 List<User> userList =new ArrayList<>(); 12 userList.add(new User(1,"zhangsan")); 13 userList.add(new User(2,"lisi")); 14 userList.add(new User(3,"wanglu")); 15 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("user")); 16 oos.writeObject(userList); 17 oos.flush(); 18 oos.close(); 19 } 20 21 }
3、反序列化多个对象
1 package JAVAADVANCE; 2 3 import java.io.FileInputStream; 4 import java.io.IOException; 5 import java.io.ObjectInputStream; 6 import java.util.List; 7 8 public class TestAdvance35TestObjectInputStreamTest02 { 9 public static void main(String[] args) throws IOException, ClassNotFoundException { 10 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("user")); 11 // Object obj=ois.readObject(); 12 // System.out.println(obj instanceof List);//返回true 13 List<User> userList=(List<User>)ois.readObject(); 14 for(User user:userList){ 15 System.out.println(user); 16 } 17 ois.close(); 18 } 19 }
4、查看执行结果:
User{name='zhangsan', no=1}
User{name='lisi', no=2}
User{name='wanglu', no=3}
五、transient关键字
1、transient关键字
表示为游离的状态,如name加上transient代表name不参与序列化
2、举例说明
以上例子User类name加上transient
1 package JAVAADVANCE; 2 import java.io.Serializable; 3 public class User implements Serializable { 4 private transient String name; 5 private int no; 6 public User() { 7 } 8 9 public User( int no,String name) { 10 this.no = no; 11 this.name = name; 12 } 13 14 @Override 15 public String toString() { 16 return "User{" + 17 "name='" + name + '\'' + 18 ", no=" + no + 19 '}'; 20 } 21 }
3、查看结果:
再次执行反序列化
User{name='null', no=1}
User{name='null', no=2}
User{name='null', no=3}
六、序列化版本号
1、 背景:
当Student源代码发生改动后,需要重新编译,会生成新的字节码文件,class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应改变。
到导致java.io.InvaildClassException;SerialVersionUID不一致的情况。
2、java语言中如何区分类:
如果类名不一样,不是同一个类;类名同样的情况下,靠序列化版本号进行区分
3、建议:
凡是类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,java虚拟机会认为是同一个类
private static final long serialVersionUID=1L;
4、Idea快速生成序列化版本号
class类,alt+回车实现
需要设置:File-Setting-Editor-Inspections-搜索serializable-Serializable class without serialVersionUID-Apply
加载全部内容