• Java序列化和反序列化


    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11804649.html

    Java中的对象序列化意思也就是说用来存储或者传输Java对象, 反序列化就是将存储起来的Java对象或者传输过来的流转化为Java对象的操作,具体的序列化操作和注意事项如下:

     首先创建一个普通的Java对象, 不实现java.io.Serializable接口;

    /**
     * 普通的Java对象 (未实现java.io.Serializable接口)
     */
    public class SerializableModel{
        
        private String id;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }

    main测试类如下:

    /**
     * main测试类
     */
    public class MainTest {
    
        public static void main(String[] args) throws Exception{
            serialObj();
        }
    
        /**
         * 序列化操作
         * @throws IOException
         */
        public static void serialObj() throws IOException {
            SerializableModel model = new SerializableModel();
            model.setId("33333");
            FileOutputStream fileOutputStream = new FileOutputStream("d://tmp/test.txt");
            ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
            outputStream.writeObject(model);
            outputStream.close();
            fileOutputStream.close();
        }
    
        /**
         * 反序列化操作
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public static void unserialObj() throws IOException, ClassNotFoundException {
            SerializableModel model = null;
            FileInputStream fileInputStream = new FileInputStream("d://tmp/test.txt");
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            model = (SerializableModel) inputStream.readObject();
            inputStream.close();
            fileInputStream.close();
            System.out.println(model.getId());
        }
    }

    执行序列化方法, 此时会抛出序列化异常,如下:

     这是因为没有实现java.io.Serializable接口, Java规定需要序列化的类都需要实现该接口, 表示对象可序列化, 没有任何方法需要实现, 仅仅是作为一个标识, 接下来我们再实现这个接口:

    /**
     * 普通的Java对象(实现序列化接口)
     */
    public class SerializableModel implements Serializable {
    
        private String id;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }

    继续执行main方法中的序列化方法, 执行成功, 生成的文本如下:

    � sr exception.SerializableModel?nQヱ L idt Ljava/lang/String;xpt 33333

    这个应该是保存下来的字节码文件, 可以看到JavaBean的名称和属性id以及属性值33333.

    接下来我们再给Java对象加上一个序列化版本号:

    /**
     * 普通的Java对象(实现序列化接口, 带序列化版本号)
     */
    public class SerializableModel implements Serializable {
    
        private static final long serialVersionUID = 0L;
    
        private String id;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }

    我们再把main方法中的serialObj()方法替换成反序列化方法unserialObj()试试看:

    public static void main(String[] args) throws Exception{
            unserialObj();
        }

     可以看到, 抛出了异常信息, 意思大概就是从流中读取的类描述信息看到的序列化版本号是-2017031617106284276(这个版本号是Java自动生成的, 因为没有指定版本号, 会自动生成一个), 而我们自己定义的序列化版本号是0, 版本不相同, 不能进行转化,所以报错.

    我们把版本号去掉再试试看:

     此时通过了编译并且打印了Java对象的id.

      总结, Java对象序列化是为了传输或者存储Java对象的, 需要序列化的对象必须实现java.io.Serializable接口, 尽量设置一个序列化版本号并且在修改了Java对象属性的时候手动去修改版本号避免反序列化的时候由于属性缺失造成转化出来的Java对象不完整而导致不必要的业务逻辑处理失败事件.

  • 相关阅读:
    Linux下登录Oracle命令行时删除键^H解决方法
    Centos7 根目录存储空间扩展方法
    js取单选按钮,复选按钮的值
    根据地址-地名获取对应的经纬度
    根据中文获得首字母大写————适用于生成编号-流水号
    邮箱格式验证demo
    百度编辑器UEditor,地址栏传值长度有限-在webConfig配置
    基于ASP.Net +easyUI框架上传图片,实现图片上传,提交表单
    Js基础知识-入门
    基础面试题——Javascript
  • 原文地址:https://www.cnblogs.com/fanerwei222/p/11804649.html
Copyright © 2020-2023  润新知