参与序列化和反序列化的对象,必须实现Serializable接口。否则会报错:Java.io.NotSerializableException
通过源代码发现,Serializable接口只是一个标志接口:
- public interface Serializable{
-
- }
这个接口中什么代码都没有,它是起标识作用的,Java虚拟机看到这个类实现了这个接口,会为该类自动生成一个序列化版本号
Java语言中是采用什么机制来区分类的?
一:首先通过类名进行比较,如果类名不一样,肯定不是同一个类
二:如果类名一样,则需要靠序列化版本号进行区分
自动生成序列化版本号的缺点:一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候Java虚拟机会认为这是一个全新的类
结论:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,这样,以后这个类即使代码修改了,但是版本号不变,Java虚拟机会认为是同一个类。
例:
- public class Student implements Serializable {
- //手动写出序列号
- private static final long serialVersionUID=1L;
- int age;
- String name;
对象类:
- public class Student implements Serializable {
- int age;
- String name;
- public Student() {
-
- }
- public Student(int age,String name) {
- this.name=name;
- this.age=age;
- }
- public void setName(String name) {
- this.name=name;
- }
- public String getName() {
- return name;
- }
- public void setAge(int age) {
- this.age=age;
- }
- public int getAge() {
- return age;
- }
- public String toString() {
- return "Student{name="+name+","+"age="+age+"}";
- }
- }
序列化:
- public static void main(String[] args) throws IOException {
- //创建对象
- Student s=new Student(3,"Alice");
- //序列化
- FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
- ObjectOutputStream oos=new ObjectOutputStream(fos);
- //序列化对象
- oos.writeObject(s);
- oos.flush();
- oos.close();
- }
反序列化:
- //反序列化
- FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
- ObjectInputStream ois=new ObjectInputStream(fis);
- //反序列化对象
- Object obj=ois.readObject();
- //输出对象
- System.out.println(obj);
- ois.close();
- //输出:Student{name=Alice,age=3}
序列化:
- //创建集合存放对象
- List
studentList=new ArrayList(); - //创建对象
- Student s1=new Student(3,"Alice");
- Student s2=new Student(5,"bob");
- Student s3=new Student(2,"rose");
- //将对象存入集合
- studentList.add(s1);
- studentList.add(s2);
- studentList.add(s3);
- //序列化
- FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
- ObjectOutputStream oos=new ObjectOutputStream(fos);
- //序列化一个集合
- oos.writeUnshared(studentList);
- oos.flush();
- oos.close();
反序列化:
- //反序列化
- FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
- ObjectInputStream ois=new ObjectInputStream(fis);
- //反序列化集合
- List
list=(List)ois.readObject(); - //遍历集合并输出
- for(Student s:list) {
- System.out.println(s);
- }
- ois.close();
- /*
- 输出:Student{name=Alice,age=3}
- Student{name=bob,age=5}
- Student{name=rose,age=2}
- */
transient关键字表示游离的,不参与序列化:
- //name用transient关键字修饰,表示name不参与序列化操作
- private transient String name;