使用不可序列化的属性序列化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,一经查实,立即删除!

相关文章

使用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" …

Java8中 Parallel Streams 的陷阱 [译]

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

ObjectStreamClass:监视Java对象的序列化

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

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

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

鼠标拖动改变DIV等网页元素的大小的最佳实践

1.初次实现 1.1 html代码 <html xmlns"http://www.w3.org/1999/xhtml" xml:lang"en" lang"en"><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>div change wid…

[WC2006]水管局长

水管局长 题目链接&#xff1a;https://www.luogu.org/problemnew/show/P4172#sub LCT 显然两个点的路径上的边最大要最小在该图最小生成树上 正删倒加&#xff0c;倒着做变成加边操作 加边时判断一下是否能形成更优的生成树&#xff0c;用LCT删除和连接操作即可 1 #include<…

JDBC 4.0鲜为人知的Clob.free()和Blob.free()方法

在会议上谈论jOOQ时&#xff0c;我总是展示此幻灯片&#xff0c;其中包含许多人们经常犯的非常常见的JDBC错误&#xff1a; 此图中的六个常见的JDBC错误 您可以找到错误吗&#xff1f; 其中一些是显而易见的&#xff0c;例如&#xff1a; 第4行&#xff1a;由于第3行的连接…

反沙箱——SetErrorMode

目录 1.前言 2.原理讲解 3.代码实现 4.参考 1.前言 利用SetErrorMode进行反沙箱的技术&#xff0c;在2010年就有被提出&#xff0c;但是之前搜了很久都没有相关内容&#xff0c;这里简单的说一下这个反沙箱的实现。反沙箱参考GandCrab5.2。 2.原理讲解 首先讲一下SetErrorMode这…

使用MyBatis和Spring构建Java Web应用程序

这篇文章将展示如何在Spring环境中使用带有MyBatis框架的MYSQL DB创建学生注册应用程序。 这是一个简单的应用程序&#xff0c;旨在在注册期间从用户收集输入详细信息&#xff0c;将详细信息保存在MYSQL DB中&#xff0c;并在登录期间对它们进行身份验证。 1.使用Maven模板创建…

codeforces 1136E-Nastya Hasn't Written a Legend

传送门&#xff1a;QAQQAQ 题意&#xff1a;有一个数组a和一个数组k&#xff0c;数组a一直保持一个性质&#xff1a;a[i 1] > a[i] k[i]。有两种操作&#xff1a;1&#xff0c;给某个元素加上x&#xff0c;但是加上之后要保持数组a的性质。比如a[i]加上x之后&#xff0c;a…

将Spring MVC RESTful Web服务迁移到Spring 4

1引言 Spring 4为MVC应用程序带来了一些改进 。 在这篇文章中&#xff0c;我将重点介绍宁静的Web服务&#xff0c;并通过采用Spring 3.2实现的项目并将其升级到Spring 4来尝试这些改进。以下几点总结了本文的内容&#xff1a; 从Spring 3.2迁移到Spring 4.0 变化中的Response…

java scrollpane 设置透明_java swing 之 JScrollPane(滚动面板)的使用

/*** java swing 之JScrollPane面板* 在设置界面时&#xff0c;可能会遇到在一个较小的容器窗体中显示一个较大部分的内容&#xff0c;这时可以使用* JScrollPane面板&#xff0c;JscrollPane面板是带滚动条的面板&#xff0c;也是一种容器&#xff0c;但是常用于布置单个* 控件…

软件工程(2019)第三次个人作业

目录 软件工程第三次作业问题描述分析并设计程序程序流程图选择覆盖标准并设计测试样例软件工程第三次作业 项目地址 问题描述 题目(1)&#xff1a;最大连续子数组和&#xff08;最大子段和&#xff09; 背景 问题&#xff1a; 给定n个整数&#xff08;可能为负数&#xff09;组…

Flutter - 创建侧滑菜单

侧滑菜单在安卓App里面非常常见&#xff0c;比如Gmail&#xff0c;Google Play&#xff0c;Twitter等。看下图 网上也有很多创建侧滑菜单的教程&#xff0c;我也来记录一下&#xff0c;自己学习创建Drawer的过程。 1. 创建一个空的App import package:flutter/material.dart;cl…

java框架白话_Java NIO框架Netty教程(二) 白话概念

"Hello World"的代码固然简单&#xff0c;不过其中的几个重要概念(类)和 Netty的工作原理还是需要简单明确一下&#xff0c;至少知道其是负责什。方便自己以后更灵活的使用和扩展。声明&#xff0c;笔者一介码农&#xff0c;不会那么多专业的词汇和缩写&#xff0c;只…

luogu4770 [NOI2018]你的名字 后缀自动机 + 线段树合并

其实很水的一道题吧.... 题意是&#xff1a;每次给定一个串\(T\)以及\(l, r\)&#xff0c;询问有多少个字符串\(s\)满足&#xff0c;\(s\)是\(T\)的子串&#xff0c;但不是\(S[l .. r]\)的子串 统计\(T\)本质不同的串&#xff0c;建个后缀自动机 然后自然的可以想到&#xff0c…