养成良好的编码习惯,显示声明UID

本文详细介绍了Java中对象序列化的实现方法及其应用场景,包括网络传输和本地存储。通过一个简单的Person类实例,演示了如何使用Serializable接口进行序列化和反序列化操作,以及如何在网络中传递对象。同时,探讨了SerialVersionUID的作用和重要性。

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

类实现Serializable接口的目的是为了可持久化,比如网络传输或本地存储,为系统的分布和异构部署提供先决支持条件。若没有序列化,现在我们熟悉的远程调用、对象数据库都不可能存在。

先来看一个简单的序列化类:

import java.io.Serializable;

/**
 * Created by 1 on 2018/8/20.
 */

public class Person implements Serializable {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

这是一个简单的JavaBean,实现了Serializable接口,可以在网络上传输,也可以本地存储然后读取。这里我们以Java消息服务(Java Message Service)方式传递该对象(即通过网络传递一个对象),定义在消息队列中的数据类型为ObjectMessage,首先定义一个消息的生产者(Producer):

public class Producer {
    public static void main(String[] args) throws Exception{
        Person person = new Person();
        person.setName("混世魔王");
        //序列化,保存到磁盘上
        SerializableUtils.writeObject(person);
    }
}

这里引入了一个工具类SerializableUtils,其作用是对一个类进行序列化和反序列化,并存储到硬盘上(模拟网络传输):

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Created by 1 on 2018/8/23.
 */

public class SerializableUtils {
    private static String FILE_NAME = "c:/obj.bin";
    //序列化
    public static void writeObject(Serializable s) {
        try {
            ObjectOutputStream oos =
                    new ObjectOutputStream(new FileOutputStream(FILE_NAME));
            oos.writeObject(s);
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //反序列化
    public static Object readObject() {
        Object obj = null;
        try {
            ObjectInput input =
                    new ObjectInputStream(new FileInputStream(FILE_NAME));
            obj = input.readObject();
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

 通过对象序列化过程,把一个对象从内存块转化为可传输的数据流,然后通过网络发送到消息消费者(Consumer)手中,并进行反序列化,生成实例对象:

public class Consumer {
    public static void main(String[] args) throws Exception{
        //反序列化
        Person person = (Person) SerializableUtils.readObject();
        System.out.println("name = " + person.getName());
    }
}

 这就是一个反序列化过程,也就是对象数据列转换为一个实例对象的过程。

SerialVersionUID也叫做流标识符(Stream Unique Identifier),即类的版本定义,它可以显示声明也可以隐式声明,生成的依据是通过包名、类名、继承关系、非私有的方法和属性,以及参数、返回值等诸多因子计算得出的。JVM在反序列化时会比较数据流中的SerialVersionUID与类的SerialVersionUID是否相同,如果相同,则认为类没有发生改变,可以把数据流load为实例对象;如果不相同,抛出InvalidClassException异常。这样可以保证一个对象即使在网络或磁盘中实现类的一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值