ACAC ObjectOutputStream(序列化)

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 1、java.io.NotSerializableException
 * 不支持序列化异常
 *
 * 2、参与序列化和反序列化的对象,必须实现Serialize接口
 * 3、通过源代码发现:Serializable接口只是一个标志接口:
 *      public interface Serializable {
 *      }
 *    接口里没有代码,作用:
 *      起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇
 *      Serializable是给java虚拟机看的,看到之后会自动生成一个序列化版本号
 *
 * 4、序列化版本号用处:
 *      java.io.InvalidClassException: Student;  无效的类异常
 *      local class incompatible:
 *      stream classdesc serialVersionUID = -426663630608197879, (Student类修改后,加了一个int a)
 *      local class serialVersionUID = 1754359514922040287 (Student类修改前)
 *
 *      java语言中是采用什么机制来区分类的?
 *          1、首先是根据类型进行比对,如果类名不一样,肯定不是同一个类
 *          2、如果类名一样,通过类的序列化版本号进行区分
 *
 *      优点:两个名字相同的类,内容不一样,(不同的人写的),对于JVM来说,是可以区分的
 *           因为这两个类都实现了Serializable接口,都有默认的序列化版本号,版本号不一样,就区分开了
 *
 *      缺陷:一旦代码确定,就不能就行修改,只要修改,就会重新编译,生成新的序列化版本号
 *           这个时候java虚拟机就会认为是一个全新的类
 *
 *     所以怎样修改呢??
 *          写一个固定不变的序列号,即使以后代码修改,但版本号不变,java虚拟机会认为是同一个类
 *
 * 一次序列化多个对象?
 *      可以,可以将对象放到集合中,序列化集合
 *      注意:参与序列化的ArrayList集合以及集合中的元素都需要实现java.io.Serializable接口
 *
 * 疑问:怎么讲解的是不能存储第二个对象?
 *      实验的是,可以存储第二个对象,也可以读出来,再存进去个集合,也可以读出来(这里不用for循环)
 *      单纯Object obj = aa.readObject() sout(obj)
 *
 */
public class ObjectOutputStreamTest {

    public static void main(String[] args) {

        Student student = new Student(111,"zhangsan");

        //序列化多个对象;
        List<Student> ss = new ArrayList<>();
        ss.add(new Student(222,"lisi"));
        ss.add(new Student(333,"wangwu"));
        ss.add(new Student(444,"zhaoliu"));

        Student sss = new Student(555,"agrfwrg");

        ObjectOutputStream oos = null;
        try {
            //序列化
            oos = new ObjectOutputStream(new FileOutputStream("myfile333"));
            //序列化对象

            oos.writeObject(student);
            oos.writeObject(ss);


            //oos.writeObject(ss);
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

/**
 *
 * 反序列化
 *
 *    刚开始写的myfile333,文件里的是Student,然后又向里面写了一个集合,
 *    sout输出oos.readObject() instanceof Student 是true 换为List就是false
 *    因为这个文件被保留了,里面的对象也是,所以要么删除内容,要么新建一个文件,写这个集合
 *
 *    结论:存多个对象会报错,用List集合进行存储
 *
 */
public class ObjectInputStreamTest {
    public static void main(String[] args) {

        ObjectInputStream oos = null;

        try {
             oos = new ObjectInputStream(new FileInputStream("myfile333"));
             //开始反序列化
             //Object obj = oos.readObject();
            //System.out.println(oos.readObject() instanceof Student);
            //List<Student> obj = (List<Student>) oos.readObject();

            Object obj = oos.readObject();
            System.out.println(obj);
            Object obj02 = oos.readObject();
            System.out.println(obj02);


            /*for(Student ss : obj) {
                System.out.println(ss);
            }*/
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

import java.io.Serializable;

/*
* transient 游离的,不参与序列化*/
public class Student implements Serializable {
    private int age;
    private transient String name;
    int a ;


    //建议手动写,不建议自动生成,随意写就行,冲突概率很低,首先类名相同的情况下,才会通过序列化版本号进行比对

    private static final long serialVersionUID = 1L;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Student() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

上一篇:ASP.NET Session State(会话状态)SQLServer模式和设置


下一篇:PBI之筛选器函数(二)