Serializable和Externalizable浅析

zz/2024/5/21 20:44:21

 

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。从而达到网络传输、本地存储的效果。

本文主要要看看JDK中使用Serializable和Externalizable接口来完成Java对象序列化,并给出部分属性序列化的几种方式,最终做出Serializable和Externalizable接口的几个方面的对比。

序列化Serializable

 要实现Java对象的序列化,只要将类实现Serializable或Externalizable接口即可。

采用类实现Serializable接口的序列化很简单,Java自动会将非transient修饰属性序列化到指定文件中去。

举个例子:

import java.io.Serializable;
import java.util.List;/*** @Type Book.java* @Desc * @author wangmengjun* @date 2017年12月1日 下午7:16:29* @version */
public class Book implements Serializable {private static final long serialVersionUID = -6212470156629515269L;/**书名*/private String name;/**ISBN*/private String isbn;/**作者*/private List<String> authors;/*** @return the name*/public String getName() {return name;}/*** @param name the name to set*/public void setName(String name) {this.name = name;}/*** @return the isbn*/public String getIsbn() {return isbn;}/*** @param isbn the isbn to set*/public void setIsbn(String isbn) {this.isbn = isbn;}/*** @return the authors*/public List<String> getAuthors() {return authors;}/*** @param authors the authors to set*/public void setAuthors(List<String> authors) {this.authors = authors;}/* (non-Javadoc)* @see java.lang.Object#toString()*/@Overridepublic String toString() {return "Book [name=" + name + ", isbn=" + isbn + ", authors=" + authors + "]";}}

然后编写一个用于序列化和反序列的小工具类,

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;/*** @Type SerializationUtil.java* @Desc * @author wangmengjun* @date 2017年12月1日 下午7:23:04* @version */
public class SerializationUtil {/*** 从一个给定的文件完成反序列化*/public static Object deserialize(String fileName) throws IOException,ClassNotFoundException {FileInputStream fis = new FileInputStream(fileName);BufferedInputStream bis = new BufferedInputStream(fis);ObjectInputStream ois = new ObjectInputStream(bis);Object obj = ois.readObject();ois.close();return obj;}/*** 将给定的对象序列化到指定的文件中去*/public static void serialize(Object obj, String fileName)throws IOException {FileOutputStream fos = new FileOutputStream(fileName);BufferedOutputStream bos = new BufferedOutputStream(fos);ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(obj);oos.close();}
}

写个测试类,测试一下:

public class SerializableTest {public static void main(String[] args) throws IOException, ClassNotFoundException {Book book = new  Book();book.setIsbn("ABC123456789");book.setName("Hello Java");book.setAuthors(Arrays.asList("John","Eric"));//book==>Book [name=Hello Java, isbn=ABC123456789, authors=[John, Eric]]System.out.println("book==>" + book);/*** 将book对象序列化到book.temp文件中去*/String fileName = "book.temp";SerializationUtil.serialize(book, fileName);/*** 从book.temp文件中,反序列化一个Book对象*/Book deserializedBook = (Book) SerializationUtil.deserialize(fileName);//deserializedBook==>Book [name=Hello Java, isbn=ABC123456789, authors=[John, Eric]]System.out.println("deserializedBook==>" + deserializedBook);}
}

一个简单的示例,就完成了Book对象的序列化和反序列化。

在上述示例中,Book对象中的所有的属性都被序列化如果里面存在部分属性,我们不想要被序列化,该如何做呢?

 

部分属性序列化

如果只想将部分属性进行序列化,可以采用如下几种方法:

  1. 使用transient关键字
  2. 添加writeObject和readObject方法
  3. 使用Externalizable实现

使用transient关键字

对属性添加transient关键字,可以防止该属性序列化~

如下示例中,我们不想isbn和authors属性被序列,添加上transient关键字实现一下~

public class Book implements Serializable {private static final long serialVersionUID = -6212470156629515269L;/** 书名 */private String name;/** ISBN */private transient String isbn;/** 作者 */private transient List<String> authors;... ... }

运行上述提到的SerializableTest.java程序,输出如下结果,我们可以看出isbn和authors的值都为null,表明这两个属性没有被序列化~

book==>Book [name=Hello Java, isbn=ABC123456789, authors=[John, Eric]] deserializedBook==>Book [name=Hello Java, isbn=null, authors=null]

添加writeObject和readObject方法

另外,我们也可以采用编写私有方法writeObject和readObject,完成部分属性的序列化。修改Book类,增加writeObject 和 readObject方法,如:

public class Book implements Serializable {private static final long serialVersionUID = -6212470156629515269L;/** 书名 */private String name;/** ISBN */private String isbn;/** 作者 */private List<String> authors;private void writeObject(ObjectOutputStream oos) throws IOException {// oos.defaultWriteObject();oos.writeObject(name);oos.writeObject(isbn);}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {// ois.defaultReadObject();name = (String) ois.readObject();isbn = (String) ois.readObject();}... ...}

 


http://www.ngui.cc/zz/2732102.html

相关文章

java8新特性_12_Stream练习

public class TestStreamApi04lianxi {List<Employee> emps Arrays.asList(new Employee("张三", 18,9999.99, Status.FREE),new Employee("李四", 38,5555.99, Status.BUSY),new Employee("王五", 50,6666.66, Status.VOCATION),new Emp…

《并发编程的艺术》第一章 并发编程的挑战

1.1 上下文切换 CPU 通 过时间 片分配算法来循 环执 行任 务 &#xff0c;当前任 务执 行一个 时间 片后会切 换 到下一个 任务 。但是&#xff0c;在切 换 前会保存上一个任 务 的状 态 &#xff0c;以便下次切 换 回 这 个任 务时 &#xff0c;可以再加 载这 个任务 的状 态…

保障消息100%投递成功、消息幂等性

一、前言 我们小伙伴应该都听说够消息中间件MQ&#xff0c;如&#xff1a;RabbitMQ&#xff0c;RocketMQ&#xff0c;Kafka等。引入中间件的好处可以起到抗高并发&#xff0c;削峰&#xff0c;业务解耦的作用。 如上图&#xff1a; &#xff08;1&#xff09;订单服务投递消息…

MySQL高级之索引面试题分析

索引优化简单案例 单表 需求&#xff1a;查询category_id为1 且 comments大于1 的情况下&#xff0c;views最多的id 1、无索引的情况下&#xff1a; 很显然&#xff0c;type是ALL&#xff0c;即最坏的情况&#xff0c;Extra还出现了Using filesort也是最坏的情况&#xff0c…

消息不丢失

大家好&#xff0c;我是君哥。 引入消息队列可以方便地实现系统解耦、削峰填谷等作用。但是消息队列使用不当&#xff0c;可能会引起消息丢失&#xff0c;在一些消息敏感的业务场景下&#xff0c;这是不允许的。今天我们来聊一聊 RocketMQ 怎么做能确保消息不丢失。 1 Rocket…

Java设计模式之《享元模式》

享元模式&#xff1a;“享”就是分享之意&#xff0c;指一物被众人共享&#xff0c;而这也正是该模式的终旨所在。 享元模式有点类似于单例模式&#xff0c;都是只生成一个对象来被共享使用。这里有个问题&#xff0c;那就是对共享对象的修改&#xff0c;为了避免出现这种情况&…

Java设计模式之《抽象工厂模式》

一、概述 抽象工厂模式是对工厂方法模式的再升级&#xff0c;但是二者面对的场景稍显差别。 工厂方法模式面对的目标一般都是单类的&#xff0c;就比如《ava设计模式之《工厂方法模式》及使用场景》中所举的例子&#xff0c;目标就是桌子这一类商品。 如果是这样的呢&#x…

Java设计模式之《构建者模式》

构建者模式&#xff0c;又称建造者模式&#xff0c;将一部负责对象的构建分为许多小对象的构建&#xff0c;最后在整合构建的模式。 构建者模式一般用在构建流程或者组成部件固定的场合&#xff0c;将这些部件分开构建成为组件对象&#xff0c;再将这些组件对象整合成为目标对象…

续流二极管

1、作用 续流二极管在电路中起到续流的作用&#xff0c;用于保护元器件不被元件产生的感应电动势击穿或烧坏&#xff0c;一般选用快速恢复二极管和肖特基二极管。 2、连接方式 将二极管反向并联在产生感应电动势的元件两端&#xff08;电感线圈&#xff0c;继电器&#xff0…

整流二极管简单介绍

整流二极管 整流二极管(rectifier diode)一种用于将交流电转变为直流电的半导体器件。硅整流二极管的击穿电压高&#xff0c;反向漏电流小&#xff0c;高温性能良好 整流二极管主要用于各种低频半波整流电路&#xff0c;如需达到全波整流需连成整流桥使用。 正向导通状态&am…
最新文章