账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    关于java序列化问题
    70
    0

    1.场景描述:最近在看序列化,遇到一些疑惑

      //父类
      public class parent implements Serializable{
            private static final long serialVersionUID = 7604030015683112269L; //UID
            private String name;
            
            //setter/getter...
      }
      //子类
      public class Child extends parent {
            //private String attr1;//序列化时注释此行代码,反序列化时取消注解
      }
    
      //测试类
      public class Test{
        public static void main(String[] args) throws Exception{
            //serializeTest(); //先序列化,添加子类新属性后,注释并反序列化
            Child c = deserializeTest();
            System.out.println(c.toString());
        }
    
        /*序列化*/
        public static void serializeTest() throws IOException {
            Child c= new Child();
            c.setName("wyy");
            ObjectOutputStream oos = null;
            try {
                oos = new ObjectOutputStream(new FileOutputStream(new File("d:/test.txt")));
                oos.writeObject(c);
                System.out.println(c.toString());
                System.out.println("序列化success");
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                oos.close();
            }
    
        }
    
        /*反序列化*/
        public static Rich deserializeTest() throws IOException {
            Child c = null;
            ObjectInputStream ois = null;
            try {
                ois = new ObjectInputStream(new FileInputStream(new File("d:/test.txt")));
                c = (Child) ois.readObject();
                System.out.println("反序列化成功");
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }finally {
                ois.close();
            }
    
            return c;
        }
      }

    2.问题描述:

    a.父类实现序列化接口
    b.子类继承父类
    c.先序列化子类对象,子类对象添加新属性后,再反序列化。抛出 InvalidClassException异常,UID不一致..
    d.子类添加序列化ID后,反序列化正常执行  
    (个人理解是序列号类似“暗号”,序列化后,即使类新增了属性“改头换面”,只要“暗号”对上,
    就可以正常识别旧的对象数据,反序列化就可以正常执行)
    

    3.疑惑点:

        在日常开发中,没有太在意序列化ID。父类实现序列化接口,当子类新增属性后,也没有遇到过上述异常啊。
    猜想是因为对象新增属性,对应的数据库也会新增相应字段,所以反序列化时仍能对应上? 
    但是平时也有用@Transient注解一些暂存字段,数据库没有对应列,也没遇到过InvalidClassException异常(猜想错误...)。
    

    为啥测试用例中,如果没有serialVersionUID,子类添加新属性后再反序列化,会报错,而开发中常增加类的属性,且类中没有serialVersionUID,却没有报错?是因为连接了数据库吗??

    ==========================================================================
    望对此了解的大佬,指点迷津...谢谢

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 川长思鸟来 普通会员 1楼

      Java序列化是指将对象的Java对象转换为字符串的过程。Java序列化有两种方式:序列化和反序列化。

      1. 使用java.io.*;

      序列化:通过使用ObjectOutputStreamObjectInputStream将对象转换为字符串。

      ```java ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("myFile.ser")); out.writeObject(obj); out.close();

      ObjectInputStream in = new ObjectInputStream(new FileInputStream("myFile.ser")); String str = (String) in.readObject(); in.close(); ```

      1. 使用Gson库

      反序列化:通过使用Gson库将字符串转换为对象。

      java String str = "Hello, World!"; Gson gson = new Gson(); MyObject obj = gson.fromJson(str, MyObject.class);

      注意,序列化和反序列化可能会出错,因为Java对象不完全能够反映它们在内存中的状态。例如,如果你的对象包含一个数组,但是它没有明确的声明为数组,那么反序列化时可能会抛出ArrayIndexOutOfBoundsException。在这种情况下,你可能需要在反序列化时使用@JsonArray注解来确保数组的存在。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部