4

文件输入和输入出处理(六)-序列化和反序列化 - 化羽羽

 2 years ago
source link: https://www.cnblogs.com/xiaoqigui/p/16393040.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

文件输入和输入出处理(六)-序列化和反序列化

序列号

  • 序列号是序列化和反序列化的唯一标识,是一个长整型数值;
  • 如果类中不自己定义序列号,系统会自动生成一个序列号;
  • 当一方实体类发生改变,而调用方的序列号是不会跟着改变的,不知道对象已修改,会导致两边序列号不一致,反序列化失败;
  • 所以要求必须手动生成一个序列号;
  • 手动生成序列号后,可以解决目标类发生改变,不影响接口调用,对象可以正确序列化,不过对象修改的属性返序列化后没有值;

序列化对象类

//如果要支持序列化操作必须实现序列化接口
//账户类
public class Account implements Serializable {
	//手动生成序列号
    private static final long serialVersionUID = 2116137267832764072L;
    
    //账户名
    private  String aname;

    //账户密码
    private String apwd;
    
    //set,get方法省略
    
    @Override
    public String toString() {
        return "Account{" +
                "aname='" + aname + '\'' +
                ", apwd='" + apwd + '\'' +
                '}';
    }
}    

序列化

使用ObjectOutputStream 类的 writeObject(Object obj)方法

//序列化对象,写入文件
public static void xlhAccount() throws IOException {
    Account account = new Account("KH96","12345");

    //使用对象输出流,将内存中的对象写入到文件
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/test/account.txt"));
    
    //直接写入对象
    oos.writeObject(account);

    oos.close();
    System.out.println("序列化对象写入成功");
}

序列化结果

2793469-20220620140424692-1857097997.png

反序列化

使用 ObjectInputStream 类的 readObject()方法

//反序列化目标对象读取写入序列化的文件,进行反序列化,变为写入的那个目标对象
public static void fxlhAccount() throws IOException, ClassNotFoundException {
    //使用对象输入流,读入写入了序列化对象的文件
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/test/account.txt"));
    
    Account account = (Account) ois.readObject();
    ois.close();
    
    //输出目标对象
    System.out.println(account.toString());

    System.out.println("读取序列化对象,反序列化成功");

}

反序列化结果

Account{aname='KH96', apwd='12345'}
读取序列化对象,反序列化成功

当类发生改变

改变后的序列化对象

//账户类
public class Account implements Serializable {
	//手动生成序列号
    private static final long serialVersionUID = 2116137267832764072L;
    
    //账户名
    private  String aname;
    
    //账户密码
    private String apwd;

    //添加手机
    private  String atel;
    
    //set,get方法省略
    
    @Override
    public String toString() {
        return "Account{" +
                "aname='" + aname + '\'' +
                ", apwd='" + apwd + '\'' +
                ", atel='" + atel + '\'' +
                '}';
    }
}

反序列化结果

Account{aname='KH96', apwd='12345', atel='null'}
读取序列化对象,反序列化成功

如果没有手动声明序列号,实体类发生改变后就会java.io.InvalidClassException异常,序列号不一致而无法进行序列化。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK