java对象序列化与反序列化

本文详细介绍了Java对象如何通过序列化为二进制文件存储,并从文件中反序列化为对象的方法,包括具体步骤、注意事项及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 目的:在开发中有时候为了考虑到访问量,所以需要优化代码,可以减少对数据库的访问,比如可以将一些不常改变的数据通过序列化的方式保存在一个文件中,然后用户再次访问的时候可以通过反序列化的方式 从文件中读取

2. 二进制文件,后缀为.dat.bat.obj.exe.com,一般指机器编译过的文件。

3. 写入序列化数据到文件中,主要是两个对象:FileOutputStream对象、ObjectOutputStream对象(负责向指定流中写入序列化的对象)

4. 从文件中读取序列化数据,主要是两个对象:FileInputStream对象、ObjectInputStream对象(负责从指定流中读取序列化数据并还原成序列化对象)

5. 序列化的读写顺序是先进先出,先写入的先读出,后写入的后读出。

6. 序列化一个对象要实现java.io.Serializable接口,对于不想序列化的数据:

7 . 不能序列化的数据:(1)对象属性为“瞬间态”(关键字声明transient(2)静态字段

8. 序列化父类子类问题:若只有子类继承了Serializable接口,而父类不继承,那么结果出来为父类某个变量

 

一、java对象序列化为二进制

写入文件:

List dataList = new ArrayList();

dataList.add(“abc”);

dataList.add(“123”);

 

String FilePath = “e:/data.dat”;

FileOutputStream fos = new FileOutputStream(FilePath);

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(dataList);

 

二、二进制反序列化为java对象

读取文件:

try{

FileInputStreamfis = new FileInputStream(FilePath);

ObjectInputStreamois = new ObjectInputStream(fis);

Listresult = (List) ois.readObject();

System.out.println(result); //输出为[abc, 123]  (序列化结果)

}catch(Exception e){

   e.printStackTrace();

}finally{

if(fis != null){ fis.close(); }

if(ois != null){ois.close(); }

}


三、实例

创建一个类,必须实现Serializable接口

public class User implements Serializable{
private static final long serialVersionUID = 1L;    
    private Integer id;
    private String name;
    private String sex;
    private String age;
    private Country country;
    @SuppressWarnings("unused")
    private User() {
        super();
    }
   //getXXX()和setXXX()方法
}

public class Country implements Serializable{
    private String id;
    private String countryName;
    private String where;
    //getXXX()和setXXX()方法
}

public class TestSerialization {
    public static void main(String[] args) {
         outputObject();
        inputObject();
    }

    private static void inputObject(){
        try {
            FileInputStream input = new FileInputStream("d:"+File.separator+"use.out");
            ObjectInputStream objInput = new ObjectInputStream(input);
            Object user =  (Object) objInput.readObject();
            System.out.println(user.toString());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }        
    }
    
    private static void outputObject() {
        FileOutputStream os;
        try {
            os = new FileOutputStream("d:"+File.separator+"use.out");
            ObjectOutputStream o = new ObjectOutputStream(os);
            Country coun = new Country("2","中国","east");
            Object user = new User(1, "zhangsan", "男","12",coun);
            o.writeObject(user);
            o.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这样可以将对象序列化为一个文件,也可以将文件反序列化为对象。


四、注意的问题

1.序列化ID问题:两个客户端AB通过网络socket传递数据,A端将对象C序列化为二进制数据再给BB反序列化得到C。但总提示反序列化不成功。

关键:JVM是否允许反序列化。这不仅决定于类路径功能代码是否一致,更决定于两个类序列化ID是否一致。

2.序列化父类子类问题:若只有子类继承Serializable接口而父类不继承,则结果出来的是父类某变量的。

转载于:https://www.cnblogs.com/DianaCody/p/5425672.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值