序列化与反序列化

本文介绍了Java序列化与反序列化,即对象与字节序列的相互转换。阐述了其必要性,如保存对象到磁盘、网络传输等。还介绍了实现方法,包括JDK库、XML、JSON、Protostuff等,并对比了JSON与XML的优缺点,同时提及Jedis需开发者自行引入序列化工具。

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

2018.8.25 晴朗的天气格外的热!!!
Java 序列化与反序列化(https://blog.youkuaiyun.com/wangloveall/article/details/7992448/)

1.Java序列化与反序列化是什么:

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

2.为什么需要Java序列化与反序列化

序列化的两种非常重要的应用:

    使用序列化将对象集合保存到磁盘文件中,并按照它们被存储的样子获取它们。
    通过网络将对象集合传送到另一台计算机上。

3.为什么只能用序列化和反序列化

    在磁盘文件中,不能去保存和恢复对象的内存地址是因为对象被重载时,它可能占据的是与原来完全不同的内存地址。
    在网络传输中,不同的处理器之间通信时,对象占据的内存地址也是完全不同。

4.序列化和反序列化的好处

序列化就是每个对象都是用一个序列号保存的,这就是这种机制被称为序列化的原因。

5.实现Java对象序列化与反序列化的方法

    (1).JDK库中的序列化API实现二进制序列化
    (2).XML
    (3).JSON
    (4).Protostaff

6.JDK库中序列化与反序列化:

(1)对象序列化包括如下步骤:

    创建一个对象输出流,它可以包装一个其他类的目标输出流,如文件输出流;
    通过对象输出流的writeObject()方法写对象。

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("empoyee.dat"));
Employee harry = new Employee("Harry Hacker", 5000, 1989, 10, 1);
Maneger boss = new Manager("Carl Cracker", 7000, 1984, 12, 15);
oos.writeObject(harry);
oos.writeObject(boss);

(2)对象反序列化包括如下步骤:

    创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
    通过对象输入流的readObject()方法以这些对象被写出的顺序读取对象并获得它们。

ObjectInputStream ois = new ObjectInputStream (new FileInputStream("empoyee.dat"));
Employee e1 = (Employee)ois.readObject();
Maneger e2 = (Manager)ois.readObject();

(3)对于那么需要序列化与反序列化的对象,对应的类必须要实现JDK库的相关API,有以下三种方法:

    若Club类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化

ObjectOutputStream采用默认的序列化方式,对Club对象的非transient的实例变量进行序列化。

ObjcetInputStream采用默认的反序列化方式,对对Club对象的非transient的实例变量进行反序列化。

    若Club类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。

ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

    若Club类实现了Externalnalizable接口,且Club类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。

ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

 

 

 

和很多NoSQL数据库(例如Memcache、Ehcache)的客户端不同,Jedis本身没有提供序列化的工具,也就是说开发者需要自己引入序列化的工具。

 (1).JDK库中的序列化API实现二进制序列化(序列化对象实现Serializable)
 private static byte[] serialize(Object object) {
        ObjectOutputStream objectOutputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(object);
            byte[] getByte = byteArrayOutputStream.toByteArray();
            return getByte;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Object unserizlize(byte[] binaryByte) {
        ObjectInputStream objectInputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        byteArrayInputStream = new ByteArrayInputStream(binaryByte);
        try {
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            Object obj = objectInputStream.readObject();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}


(2).XML
首先,必须要在要被序列化的对象的类上注释@XmlRootElement(name = "Club")
 private static String serialize(Object object) {
        StringWriter stringWriter = null;
        try {
            stringWriter = new StringWriter();
            JAXBContext jContext = JAXBContext.newInstance(object.getClass());
            Marshaller marshaller = jContext.createMarshaller();
            marshaller.marshal(object, stringWriter);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return stringWriter.toString();
    }

    private static Object unserizlize(Class<Club> clazz, String xmlString) {

        Object xmlObject = null;
        try {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            StringReader stringReader = new StringReader(xmlString);
            xmlObject = unmarshaller.unmarshal(stringReader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return xmlObject;
    }

(3)使用JSON实现序列化和反序列化


Java下常用的JSON工具类库主要有以下几种:

    JSON-lib
    FastJson
    Jackson
    Gson

以JSON-lib为例:
private static String serialize(Object object) {
        JSONObject jsonObject = JSONObject.fromObject(object);
        String getString = jsonObject.toString();
        return getString;

    }

    private static Object unserizlize(String jsonString) {
        new JSONObject();
        JSONObject jObject = JSONObject.fromObject(jsonString);
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "MM/dd/yyyy HH:mm:ss" }));
        Object jsonObject = JSONObject.toBean(jObject, Club.class);
        return jsonObject;
    }


以FastJson为例:
Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。

(2)FastJson优点:

    FastJson数度快,无论序列化和反序列化,都是目前Java中最快的。
    功能强大(支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum)。
    零依赖(没有依赖其它任何类库)

(3)FastJson主要API


    1. 将对象序列化成json字符串

    String com.alibaba.fastjson.JSON.toJSONString(Object object)

    2. 将json字符串反序列化成对象

    <T> Project com.alibaba.fastjson.JSON.parseObject(String text, Class<T> clazz)

    3. 将json字符串反序列化成JSON对象

    JSONObject com.alibaba.fastjson.JSON.parseObject(String text)

    4.根据key 得到json中的json数组

    JSONArray com.alibaba.fastjson.JSONObject.getJSONArray(String key)

    5. 根据下标拿到json数组的json对象

    JSONObject com.alibaba.fastjson.JSONArray.getJSONObject(int index)

    6.. 根据key拿到json的字符串值

    String com.alibaba.fastjson.JSONObject.getString(String key)

    7. 根据key拿到json的int值

    int com.alibaba.fastjson.JSONObject.getIntValue(String key)

    8. 根据key拿到json的boolean值

    boolean com.alibaba.fastjson.JSONObject.getBooleanValue(String key)
    实例:
    private static String serialize(Object object) {
        String getString = JSON.toJSONString(object);
        return getString;
        }

        private static Object unserizlize(String jsonString) {
        Object jsonObject = JSON.parseObject(jsonString, Club.class);
        return jsonObject;
        }


JSON与XML优缺点对比分析

(1)JSON的优点:

    与XML相比,JSON更加的简洁,我们可以一眼就看出其中的内容,方便检查排错
    JSON更加轻量级,不管是编写,传输,还是解析都更加高效
    JSON在传输过程中采用了压缩技术,更加的节省宽带
    众多的语言支持,如javascript,python,C,C++等主流语言都支持
    因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。

(2)XML的优点:

    格式统一,符合标准;
    容易与其他系统进行远程交互,数据共享比较方便

(3)XML的缺点:

    XML文件庞大,文件格式复杂,传输占带宽;
    服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
    客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
    服务器端和客户端解析XML花费较多的资源和时间。

(4)使用Protostuff实现序列化与反序列化
https://blog.youkuaiyun.com/ssjq123/article/details/82055319

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来日可期1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值