使用不可序列化的属性序列化Java对象

人们可能有多种原因想要使用自定义序列化而不是依赖Java的默认序列化。 最常见的原因之一是为了提高性能,但是编写自定义序列化的另一个原因是不支持默认序列化机制。 具体来说,如本博文所述,自定义序列化可用于允许将较大的对象序列化,即使该对象的属性本身不能直接序列化也是如此 。

下一个代码清单显示了一个简单的类,该类用于将给定类序列化为提供名称的文件,并从该文件中反序列化对象。 我将在本文中使用它来演示序列化。

SerializationDemonstrator.java

package dustin.examples.serialization;import static java.lang.System.out;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;/*** Simple serialization/deserialization demonstrator.* * @author Dustin*/
public class SerializationDemonstrator
{/*** Serialize the provided object to the file of the provided name.* @param objectToSerialize Object that is to be serialized to file; it is*     best that this object have an individually overridden toString()*     implementation as that is used by this method for writing our status.* @param fileName Name of file to which object is to be serialized.* @throws IllegalArgumentException Thrown if either provided parameter is null.*/public static <T> void serialize(final T objectToSerialize, final String fileName){if (fileName == null){throw new IllegalArgumentException("Name of file to which to serialize object to cannot be null.");}if (objectToSerialize == null){throw new IllegalArgumentException("Object to be serialized cannot be null.");}try (FileOutputStream fos = new FileOutputStream(fileName);ObjectOutputStream oos = new ObjectOutputStream(fos)){oos.writeObject(objectToSerialize);out.println("Serialization of Object " + objectToSerialize + " completed.");}catch (IOException ioException){ioException.printStackTrace();}}/*** Provides an object deserialized from the file indicated by the provided* file name.* * @param <T> Type of object to be deserialized.* @param fileToDeserialize Name of file from which object is to be deserialized.* @param classBeingDeserialized Class definition of object to be deserialized*    from the file of the provided name/path; it is recommended that this*    class define its own toString() implementation as that will be used in*    this method's status output.* @return Object deserialized from provided filename as an instance of the*    provided class; may be null if something goes wrong with deserialization.* @throws IllegalArgumentException Thrown if either provided parameter is null.*/public static <T> T deserialize(final String fileToDeserialize, final Class<T> classBeingDeserialized){if (fileToDeserialize == null){throw new IllegalArgumentException("Cannot deserialize from a null filename.");}if (classBeingDeserialized == null){throw new IllegalArgumentException("Type of class to be deserialized cannot be null.");}T objectOut = null;try (FileInputStream fis = new FileInputStream(fileToDeserialize);ObjectInputStream ois = new ObjectInputStream(fis)){objectOut = (T) ois.readObject();out.println("Deserialization of Object " + objectOut + " is completed.");}catch (IOException | ClassNotFoundException exception){exception.printStackTrace();}return objectOut;}
}

下一个代码清单说明了如何使用SerializationDemonstrator类对标准Java字符串(可序列化)进行序列化和反序列化。 屏幕快照显示在代码清单之后,并通过SerializationDemonstrator类的serializedeserialize serialize方法显示了运行String的输出(在NetBeans中)。

在字符串上运行SerializationDemonstrator方法

SerializationDemonstrator.serialize("Inspired by Actual Events", "string.dat");
final String stringOut = SerializationDemonstrator.deserialize("string.dat", String.class);

outputStringSerializationDemonstrator

接下来的两个代码清单是针对Person.java类及其作为属性类型的一个类( CityState.java )。 尽管Person实现了Serializable ,但CityAndState类没有实现。

人.java

package dustin.examples.serialization;import java.io.Serializable;/*** Person class.* * @author Dustin*/
public class Person implements Serializable
{private String lastName;private String firstName;private CityState cityAndState;public Person(final String newLastName, final String newFirstName,final CityState newCityAndState){this.lastName = newLastName;this.firstName = newFirstName;this.cityAndState = newCityAndState;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}@Overridepublic String toString(){return this.firstName + " " + this.lastName + " of " + this.cityAndState;}
}

CityAndState.java

package dustin.examples.serialization;/*** Simple class storing city and state names that is NOT Serializable.* * @author Dustin*/
public class CityState
{private final String cityName;private final String stateName;public CityState(final String newCityName, final String newStateName){this.cityName = newCityName;this.stateName = newStateName;}public String getCityName(){return this.cityName;}public String getStateName(){return this.stateName;}@Overridepublic String toString(){return this.cityName + ", " + this.stateName;}
}

下一个代码清单演示如何在具有不可序列化的CityState的可序列化Person类上运行SerializationDemonstrator 。 代码清单后是NetBeans中输出的屏幕快照。

在具有不可序列化的CityState的可序列化人员上运行SerializationDemonstrator方法

final Person personIn = new Person("Flintstone", "Fred", new CityState("Bedrock", "Cobblestone"));
SerializationDemonstrator.serialize(personIn, "person.dat");final Person personOut = SerializationDemonstrator.deserialize("person.dat", Person.class);

serializationDemonstratorOnSerializablePersonNonSerializableCityState

在这种情况下, CityState类是我自己的类,可以将其设置为Serializable。 但是,假设该类是第三方框架或库的一部分,并且我无法更改该类本身,则可以将Person更改为使用自定义序列化和反序列化,并正确使用CityState 。 这在适用于Person的类SerializablePerson的下一个代码清单中显示。

SerializablePerson.java

package dustin.examples.serialization;import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;/*** Person class.* * @author Dustin*/
public class SerializablePerson implements Serializable
{private String lastName;private String firstName;private CityState cityAndState;public SerializablePerson(final String newLastName, final String newFirstName,final CityState newCityAndState){this.lastName = newLastName;this.firstName = newFirstName;this.cityAndState = newCityAndState;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}@Overridepublic String toString(){return this.firstName + " " + this.lastName + " of " + this.cityAndState;}/*** Serialize this instance.* * @param out Target to which this instance is written.* @throws IOException Thrown if exception occurs during serialization.*/private void writeObject(final ObjectOutputStream out) throws IOException{out.writeUTF(this.lastName);out.writeUTF(this.firstName);out.writeUTF(this.cityAndState.getCityName());out.writeUTF(this.cityAndState.getStateName());}/*** Deserialize this instance from input stream.* * @param in Input Stream from which this instance is to be deserialized.* @throws IOException Thrown if error occurs in deserialization.* @throws ClassNotFoundException Thrown if expected class is not found.*/private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException{this.lastName = in.readUTF();this.firstName = in.readUTF();this.cityAndState = new CityState(in.readUTF(), in.readUTF());}private void readObjectNoData() throws ObjectStreamException{throw new InvalidObjectException("Stream data required");}
}

上面的代码清单显示SerializablePerson具有自定义的writeObject和readObject方法,以支持自定义的序列化/反序列化, CityState适当地处理其CityState序列化类型CityState属性。 接下来显示用于通过SerializationDemonstrator运行该类的代码片段以及这样做的成功输出。

在SerializablePerson上运行SerializationDemonstrator

final SerializablePerson personIn = new SerializablePerson("Flintstone", "Fred", new CityState("Bedrock", "Cobblestone"));
SerializationDemonstrator.serialize(personIn, "person.dat");final SerializablePerson personOut = SerializationDemonstrator.deserialize("person.dat", SerializablePerson.class);

serializationDemonstratorOnSerializablePersonPlusNonSerializableCityState

上面描述的方法将允许将不可序列化的类型用作可序列化类的属性,而无需使那些字段处于瞬态状态。 但是,如果前面显示的CityState实例需要在多个可序列化的类中使用,则最好使用可序列化的装饰器装饰CityState类,然后在需要序列化的类中使用该序列化的装饰器类。 下一个代码清单显示SerializableCityState ,它用序列化的版本装饰CityState

SerializableCityState

package dustin.examples.serialization;import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;/*** Simple class storing city and state names that IS Serializable. This class* decorates the non-Serializable CityState class and adds Serializability.* * @author Dustin*/
public class SerializableCityState implements Serializable
{private CityState cityState;public SerializableCityState(final String newCityName, final String newStateName){this.cityState = new CityState(newCityName, newStateName);}public String getCityName(){return this.cityState.getCityName();}public String getStateName(){return this.cityState.getStateName();}@Overridepublic String toString(){return this.cityState.toString();}/*** Serialize this instance.* * @param out Target to which this instance is written.* @throws IOException Thrown if exception occurs during serialization.*/private void writeObject(final ObjectOutputStream out) throws IOException{out.writeUTF(this.cityState.getCityName());out.writeUTF(this.cityState.getStateName());}/*** Deserialize this instance from input stream.* * @param in Input Stream from which this instance is to be deserialized.* @throws IOException Thrown if error occurs in deserialization.* @throws ClassNotFoundException Thrown if expected class is not found.*/private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException{this.cityState = new CityState(in.readUTF(), in.readUTF());}private void readObjectNoData() throws ObjectStreamException{throw new InvalidObjectException("Stream data required");}
}

可以直接在Person类中使用此可序列化的修饰器,并且封闭的Person可以使用默认序列化,因为其字段都是可序列化的。 这显示在Person改编的Person2的下一个代码清单中。

Person2.java

package dustin.examples.serialization;import java.io.Serializable;/*** Person class.* * @author Dustin*/
public class Person2 implements Serializable
{private final String lastName;private final String firstName;private final SerializableCityState cityAndState;public Person2(final String newLastName, final String newFirstName,final SerializableCityState newCityAndState){this.lastName = newLastName;this.firstName = newFirstName;this.cityAndState = newCityAndState;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}@Overridepublic String toString(){return this.firstName + " " + this.lastName + " of " + this.cityAndState;}
}

可以像下面的代码清单中所示那样执行该代码,然后在NetBeans输出窗口中看到其输出。

针对Person2 / SerializableCityState运行SerializationDemonstrator

final Person2 personIn = new Person2("Flintstone", "Fred", new SerializableCityState("Bedrock", "Cobblestone"));
SerializationDemonstrator.serialize(personIn, "person.dat");final Person2 personOut = SerializationDemonstrator.deserialize("person.dat", Person2.class);

serializedOutputDemoPerson2SerializedCityState

自定义序列化可用于允许对具有不可序列化类型的属性的类进行序列化,而不会使那些不可序列化类型的属性瞬变。 当可序列化的类需要使用不可序列化且无法更改的类型的属性时,这是一种有用的技术。

参考:来自JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客上的使用不可序列化属性序列化Java对象 。

翻译自: https://www.javacodegeeks.com/2014/02/serializing-java-objects-with-non-serializable-attributes.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷 P3455 [POI2007]ZAP-Queries (莫比乌斯反演)

题意: 给定a&#xff0c;b&#xff0c;d求gcd(x,y)d的对数(1<x<a,1<y<b) 思路&#xff1a;按照套路来先设f(n)为gcd(x,y)n的对数,g(n)表示为 n | gcd(x,y)的对数,则g(n)∑n|df(d)a/n*b/n f(n)∑n|dg(d)*mu(d/n),令td/n则f(n)∑t1g(t*n)*mu(t)&#xff0c;然后求f(d…

java thread isalive_Java线程编程中isAlive()和join()的使用详解

一个线程如何知道另一线程已经结束&#xff1f;Thread类提供了回答此问题的方法。有两种方法可以判定一个线程是否结束。第一&#xff0c;可以在线程中调用isAlive()。这种方法由Thread定义&#xff0c;它的通常形式如下&#xff1a;final boolean isAlive( )如果所调用线程仍在…

Gradle sync failed: Read timed out

23:52 Gradle sync started23:54 Gradle sync failed: Read timed outConsult IDE log for more details (Help | Show Log) (2 m 29 s 815 ms) 原因是Gradle下载超时 一.下载 https://gradle.org/releases/ 二.安装 $ mkdir /opt/gradle $ unzip -d /opt/gradle gradle-…

JQuery知识点

jQueqry01--------------------------------------------------------------------------------------------------1&#xff09;$(function(){ //相当于windows.onload,等待文档加载完毕后&#xff0c;再执行 } ) 2&#xff09;jquery中的时间添加&#xff0c;全部采用现代时…

使用Spring跟踪异常–第2部分–委托模式

在上一个博客中 &#xff0c;我开始谈论需要弄清楚您的应用程序在生产环境中是否行为异常。 我说过&#xff0c;监视应用程序的一种方法是检查其日志文件是否存在异常&#xff0c;如果发现异常&#xff0c;则采取适当的措施。 显然&#xff0c;日志文件会占用数百兆的磁盘空间&…

aix java home_java程序员工作日子一(java_home 配置)

安装 JDK 和设置 JAVA_HOME如果您尚未在系统中安装 Java Development Kit (JDK) 和/或尚未设置 JAVA_HOME&#xff0c;则在尝试安装 Java CAPS 之前&#xff0c;需要安装 JDK 并设置 JAVA_HOME。以下任务提供了在 UNIX 或 Windows 系统上安装 JDK 和设置 JAVA_HOME 所需的信息。…

MySQL 开启远程访问权限 | 宝塔系统

1.进入 MySQL 管理菜单 2.选择权限为所有人 转载于:https://www.cnblogs.com/Skrillex/p/10728681.html

基于vue实现百度离线地图

基于vue实现百度离线地图 1. 百度地图API文件获取 有网络 的情况下&#xff0c;需引入百度地图API文件。如下&#xff1a; <script type"text/javascript" src"http://api.map.baidu.com/api?v3.0&ak您的密钥"></script> 无网络 的情况下…

日期插件rolldate.js的使用

日期插件rolldate.js的使用 下载地址&#xff1a;http://www.jq22.com/jquery-info19834 效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" …

MapReduce算法–了解数据连接第二部分

自从我上一次发布以来已经有一段时间了&#xff0c;就像我上一次大休息一样&#xff0c;我正在Coursera上一些课程。 这次是Scala中的函数式编程 原理和反应式编程原理 。 我发现它们都是不错的课程&#xff0c;如果有时间的话&#xff0c;建议您选一门。 在本文中&#xff0c;…

C: City----逆向并查集

C: City 时间限制: 1 s 内存限制: 128 MB 题目描述 如果城市A和城市B互通&#xff0c;城市B和城市C互通&#xff0c;那么城市A和城市C也互通&#xff0c;A、B、C三个城市算一个聚集点。先已知有n个城市和m条道路&#xff0c;想求的是有几个聚集点&#xff1f;但小S觉…

java menu字体_Java开发网 - 请问如何让菜单字体变宋体?

Posted by:scottdingPosted on:2003-01-23 12:44贴出了大部分&#xff0c;你看看想改什么吧。Font font new Font("宋体",Font.PLAIN,14);UIManager.put("Button.font",font);UIManager.put("ToggleButton.font",font);UIManager.put("Rad…

Java8中 Parallel Streams 的陷阱 [译]

转载自https://www.cnblogs.com/imyijie/p/4478074.html Java8 提供了三个我们渴望的重要的功能:Lambdas 、 Stream API、以及接口的默认方法。不过我们很容易滥用它们甚至破坏自己的代码。 今天我们来看看Stream api&#xff0c;尤其是 parallel streams。这篇文章概述了其中的…

自定义消息提示框

使用原生JavaScript简单封装的一个消息提示模态框&#xff0c;如果谁有更好的方式可以分享&#xff0c;谢谢&#xff01; <!DOCTYPE html> <html lang"en"><head><title></title><meta charset"UTF-8"><meta name&…

ObjectStreamClass:监视Java对象的序列化

ObjectStreamClass可以是有用的类&#xff0c;用于分析JVM中加载的序列化类的序列化特征。 这篇文章介绍了此类提供的有关已加载序列化类的一些信息。 ObjectStreamClass提供了两个用于查找类的静态方法&#xff1a; lookup&#xff08;class&#xff09;和lookupAny&#xff…

@Transcational特性

捕获RuntimeException捕获Error并不捕获Checked Exception在方法中使用Transcational注解时候&#xff0c;通过throw new Exception&#xff08;&#xff09;&#xff0c;在发生异常的时候不会进行回滚&#xff0c;可以使用throw new RuntimeException&#xff08;&#xff09;…

SpringBoot集成Thymeleaf前端模版

1、在application.properties配置文件中添加 thymeleaf 的配置信息 spring.datasource.driverClassNamecom.mysql.jdbc.Driver spring.datasource.urljdbc:mysql://localhost:3306/test spring.datasource.usernameroot spring.datasource.passwordrootspring.thymeleaf.modeHT…

00005在java结果输出_Java-005-运算符详解

计算机的最基本用途之一就是执行数学运算,作为一门计算机语言Java也提供了套丰富的运算符来操纵变量, 可以把运算符分成以下几组算术运算符、关系运算符、位运算符、逻辑运算符、赋值运算符、其他运算符。①算术运算符用在数学表达式中它们的作用和在数学中的作用一样 表格中的…

spring data jpa 分页查询

法一&#xff08;本地sql查询,注意表名啥的都用数据库中的名称&#xff0c;适用于特定数据库的查询&#xff09; public interface UserRepository extends JpaRepository<User, Long> {Query(value "SELECT * FROM USERS WHERE LASTNAME ?1",countQuery &…

Python之递归

递归的意思是函数自己调用自己。递归次数&#xff1a;递归如果是死循环&#xff0c;最多执行999次。count0 def say():global countcount1print(say)print(count)say()say() #结果&#xff1a; # say # 1 # ... # say # 997 # say # RecursionError: maximum recursion depth e…