zoukankan      html  css  js  c++  java
  • java序列化(一)

    今天我们来探讨一下java的序列化与反序列化。之前对此一直有概念,但是并没有真正的去测试。大家都知道,所谓的序列化就是把java代码读取到一个文件中,反序列化就是从文件中读取出对象。在网络传输过程中,我们也需要对对象进行序列化,因为一个对象是不能进行传输的。下面先上代码

    package serializable;
    
    import java.io.*;
    
    public class SerializableTest implements Serializable {
        private static final Long serialVersionUID = 1L;
    
        private String name;
    
        public String sex;
    
        protected int age;
    
        private static int id;
    
        transient private float height;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public static int getId() {
            return id;
        }
    
        public static void setId(int id) {
            SerializableTest.id = id;
        }
    
        public float getHeight() {
            return height;
        }
    
        public void setHeight(float height) {
            this.height = height;
        }
    
        public static void main(String[] args) throws Exception {
            serializable();
            deSerializable();
        }
    
        /**
         * 序列化
         * @throws IOException
         */
        private static void serializable() throws IOException {
            SerializableTest serializableTest = new SerializableTest();
            serializableTest.setAge(25);
            serializableTest.setId(122528);
            serializableTest.setName("张三");
            serializableTest.setSex("男");
            serializableTest.setHeight(175);
    
            FileOutputStream fos = new FileOutputStream("serializableTest.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(serializableTest);
            oos.flush();
            oos.close();
        }
    
        /**
         * 反序列化
         * @throws Exception
         */
        public static void deSerializable() throws Exception{
            FileInputStream fis = new FileInputStream("serializableTest.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            SerializableTest serializableTest = (SerializableTest) ois.readObject();
            System.out.println("serializableTest.getAge() = " + serializableTest.getAge());
            System.out.println("serializableTest.getName() = " + serializableTest.getName());
            System.out.println("serializableTest.getSex() = " + serializableTest.getSex());
            System.out.println("serializableTest.getHeight() = " + serializableTest.getHeight());
            System.out.println("serializableTest.getId() = " + serializableTest.getId());
        }
    }

    此类中,包括了private、public、protected、static和transient修饰的属性,我们先看下运行结果

    serializableTest.getAge() = 25
    serializableTest.getName() = 张三
    serializableTest.getSex() = 男
    serializableTest.getHeight() = 0.0
    serializableTest.getId() = 122528

    可以发现transient修饰的属性并没有被序列化,这也是我们所认知的。但是static修饰的属性也不应该被序列化才对,现在对象已经被我们读到文件中了,在单独执行一次反序列化方法。

        public static void main(String[] args) throws Exception {
            //serializable();
            deSerializable();
        }

    执行结果如下:

    serializableTest.getAge() = 25
    serializableTest.getName() = 张三
    serializableTest.getSex() = 男
    serializableTest.getHeight() = 0.0
    serializableTest.getId() = 0

    现在得到的Id的值是0,也就是这个值并没有被序列化存储到文件中。

    最后再说一下序列化版本号的意义。在我的理解看来,次版本号就是为了保证程序的稳定性,如果我们不声明的话,如果开始的一个对象序列化时,会为我们自动生成一个版本,如果后面我们修改了此类,那么在反序列化的时候,会发生版本不一致的问题。所以一般我们会声明成一个定值,这样就能防止上述问题。我们可以把版本代码注释掉,运行一下反序列化结果如下:

    Exception in thread "main" java.io.InvalidClassException: serializable.SerializableTest; local class incompatible: stream classdesc serialVersionUID = 4564223277371155727, local class serialVersionUID = 5130976784646098676
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
        at serializable.SerializableTest.deSerializable(SerializableTest.java:89)
        at serializable.SerializableTest.main(SerializableTest.java:60)
  • 相关阅读:
    表数据转换为insert语句
    Google Map Api 谷歌地图接口整理
    VS预生成事件命令行 和 生成后事件命令行
    C#程序开机运行
    枚举数据源化
    winform分页管理
    数据库访问驱动
    sql时间格式
    sysobjects.xtype介绍
    编码标准的多样性
  • 原文地址:https://www.cnblogs.com/wanghq1994/p/12144282.html
Copyright © 2011-2022 走看看