JavaSE——IO(下)(Properties类、序列化与反序列化)

第3节 IO(下)

一、.properties文件与Properties类

1.1 .properties文件介绍

.properties文件一种属性文件,以键值对 的格式存储内容,在Java中可以使用Properties类来读取这个文件,一般来说它作为一些参数的存储,作为配置文件使用。

1.2 Properties类

它是Hashtable的子类,使用键值对来存储数据。

构造方法:

在这里插入图片描述

方法:

1、根据键获取值:

在这里插入图片描述

2、将键值对打印到指定的输出流:

在这里插入图片描述

3、从输入字节流或字符流中读取全部内容:

在这里插入图片描述

4、返回所有键的枚举:

在这里插入图片描述

5、新增键值对:

在这里插入图片描述

6、存储到字节输出流或字符输出流,comment是备注,写在存储文件的开头:

在这里插入图片描述

7、返回所有的值,以Set类型:

在这里插入图片描述

看个例子:

package com.kaikeba.coreclasslibrary.io;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;public class properties {public static void main(String[] args) throws IOException {//.properties文件与Properties类//新建一个Properties对象Properties ppt = new Properties();//新建键值对ppt.setProperty("name","三体");ppt.setProperty("info","科幻小说");//要写入的字符流FileWriter fw = new FileWriter("book.properties");//往fw中存储该键值对集合的对象,备注为"存储的图书"ppt.store(fw, "存储的图书");fw.close();//从.properties文件读取属性Properties ppt2 = new Properties();Reader r = new FileReader("book.properties");ppt2.load(r);System.out.println(ppt.get("name"));System.out.println(ppt.get("info"));}
}输出为:
三体
科幻小说

且book.properties文件中存储的内容为:

在这里插入图片描述

最上面是备注信息,使用了Unicode编码。

二、序列化与反序列化

Java序列化是指把java对象转换为字节序列的过程 ,Java反序列化是指把字节序列恢复为java对象的过程通过序列化和反序列化实现网络传输、本地存储的目的

在这里插入图片描述

2.1 Serializable实现Java序列化

要实现java对象的序列化,只要将类实现标识接口 ——Serializable接口即可,不需要我们重写任何方法就可以实现序列化。

编写书籍类:

package com.kaikeba.coreclasslibrary.io.serializable;import java.io.Serializable;public class Book implements Serializable {private String name;private String info;private Person user;@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", info='" + info + '\'' +", user=" + user +'}';}public Book() {}public Book(String name, String info, Person user) {this.name = name;this.info = info;this.user = user;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public Person getUser() {return user;}public void setUser(Person user) {this.user = user;}
}

编写借书人类:注意Book中有Person类的对象属性,所以Person类也要实现Serializable接口

package com.kaikeba.coreclasslibrary.io.serializable;import java.io.Serializable;public class Person implements Serializable {private String name;private int age;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

编写序列化和反序列化:

package com.kaikeba.coreclasslibrary.io.serializable;import java.io.*;public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {//序列化Person p = new Person("smile", 23);Book b = new Book("三体", "科幻小说", p);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"));oos.writeObject(b);oos.close();//反序列化ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"));Book book = (Book) ois.readObject();System.out.println(book);}
}

结果如下:

原始对象:
Book{name='三体', info='科幻小说', user=Person{name='smile', age=23}}
反序列化之后的对象:
Book{name='三体', info='科幻小说', user=Person{name='smile', age=23}}

主要是使用到了ObjectOutputStreamObjectInputStream类,ObjectOutputStream类使用writeObject将对象写到文件中,ObjectInputStream类使用readObject将对象从文件中读取出来。

2.2 部分属性的序列化

实现部分字段序列化的方式:

  • 使用transient修饰符

  • 使用static修饰符

  • 默认方法writeObject和readObject

  • Externalizable实现

2.2.1 使用transient修饰符

修改实体类,将实体类中不想被序列化的属性添加transient修饰符。

public class Book implements Serializable {private String name;private transient String info;private Person user;... public class Person implements Serializable {private String name;private transient int age; ... 

结果如下:

原始对象:
Book{name='三体', info='科幻小说', user=Person{name='smile', age=23}}
反序列化之后的对象:
Book{name='三体', info='null', user=Person{name='smile', age=0}}

transient修饰的属性都没有被序列化,因此反序列化的结果也是默认值。

2.2.2 使用static修饰符

static修饰符修饰的属性会参与序列化,但是如果在反序列化的时候对其进行重新赋值,反序列化后的结果会随之改变:

public class Book implements Serializable {private String name;private static String info;private Person user;...public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {//序列化Person p = new Person("smile", 23);Book b = new Book("三体", "科幻小说", p);System.out.println("原始对象:\n"+b);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"));oos.writeObject(b);oos.close();//反序列化b.setInfo("中国最牛的科幻小说");ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"));Book book = (Book) ois.readObject();System.out.println("反序列化之后的对象:\n"+book);}
}

结果:

原始对象:
Book{name='三体', info='科幻小说', user=Person{name='smile', age=23}}
反序列化之后的对象:
Book{name='三体', info='中国最牛的科幻小说', user=Person{name='smile', age=23}}

解释:其实就是静态属性被修改之后,因为所有对象都是用的同一个内容,所以反序列化的静态属性也就变了。

2.2.3 默认方法writeObject和readObject

   在Book中添加两个方法:
public class Book implements Serializable {private String name;private String info;private Person user;private void writeObject(ObjectOutputStream oos) throws IOException {System.out.println("writeObject---------------");oos.writeObject(name);oos.writeObject(user);}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {System.out.println("readObject----------------");name = (String) ois.readObject();user = (Person) ois.readObject();}...

结果为:

原始对象:
Book{name='三体', info='科幻小说', user=Person{name='smile', age=23}}
writeObject---------------
readObject----------------
反序列化之后的对象:
Book{name='三体', info='null', user=Person{name='smile', age=23}}

info属性没有写入两个函数中,就没有被序列化。

源码分析:

注意:添加的两个方法必须是private void修饰的,否则不生效。

首先看一下Serializable接口的描述:

在这里插入图片描述

ObjectStreamClass类:在序列化(反序列化)的时候,ObjectOutputStreamObjectInputStream)会寻找目标类中私有的writeObjectreadObject)方法,赋值给变量writeObjectMethodreadObjectMethod)。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

通过上面这段代码可以知道,如果writeObjectMethod ≠ null(目标类中定义了私有的writeObject方法),那么将调用目标类中的writeObject方法,如果writeObject == null,那么将调用默认的defaultWriteMethod方法来读取目标类中的属性。

readObject的调用逻辑和WriteObject一样。

总结一下,如果目标类中没有定义私有的writeObjectreadObject方法,那么序列化和反序列化的时候讲调用默认的方法来根据目标类中的属性来进行序列化和反序列化,而如果目标类中定义了私有的writeObjectreadObject方法,那么序列化和反序列化的时候讲调用目标类指定的writeObjectreadObject方法来实现。

2.3 Externalizable实现java序列化

实现部分属性序列化的方式的第四种,通过Externalizable接口。

Externalizable继承自Serializable接口,使用Externalizable接口需要实现readExternal方法和writeExternal方法来实现序列化和反序列化。

在这里插入图片描述

Externalizable接口继承自Serializable接口,所以实现Externalizable接口也能实现序列化和反序列化。Externalizable接口中定义了writeExternalreadExternal两个抽象方法,这两个方法其实对应Serializable接口的writeObjectreadObject方法,可以这样理解:Externalizable接口被设计出来的目的就是为了抽象出writeObjectreadObject这两个方法,但是目前这个接口使用的并不多。

三、Serializable vs Externalizable

区别SerializableExternalizable
实现复杂度实现简单,java对其有内建支持实现复杂,由开发人员自己完成
执行效率所有对象由java统一保存,性能较低开发人员决定哪个对象保存,可能造成速度提升
保存信息保存时占用空间大部分存储,可能造成空间减少
使用频率偏低

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

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

相关文章

VS调试dll详细过程记录

VS调试dll详细过程记录 qianghaohao(孤狼) 前言:在我们写的程序中有时候调用dll,并且需要跟踪dll中的函数,此时直接调试调用dll的工程是无法跳进dll的函数的,此时我们可以启动dll工程 来跟踪程序的走向。注意:要有…

谁在真正领跑 5G:技术创新和标准

来源:云头条5G是包括美国总统特朗普在内的所有人都在谈论的新技术。所以,每家公司自然都想谈论5G以及如何领跑这个领域。然而现实情况是,移动5G是一项涵盖甚广的无线标准,它改变了我们对蜂窝通信的认识,并前所未有地拓…

JavaSE——XML与JSON(语法格式、解析内容)

第6节 XML与JSON 一、XML 1.1 XML简介 XML全称为可扩展标记语言(extensible Markup Language) 。 特性: xml具有平台无关性,是一门独立的标记语言; xml具有自我描述性。 用途: 网络数据传输 数据存…

三大阶段,四大领域,详解你不知道的AIoT!

AIoT即AIIoT,指的是人工智能技术与物联网在实际应用中的落地融合。目前,越来越多的行业及应用将AI与IoT结合到了一起,AIoT已经成为各大传统行业智能化升级的最佳通道,也是未来物联网发展的重要方向。来源:物联网智库AI…

人类为什么会同情机器人,是否需要禁止虐待机器人

6月14日,一段形似波士顿动力机器人Atlas反击人类的视频在网络热传,制作这款视频的团队Corridor Digital,是一家位于洛杉矶的美国制作工作室。自2010年以来,一直以制作与流行文化相关的病毒在线短片视频而闻名。Corridor Digital由…

dubbo学习总结——思维导图

Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的、轻量级的开源Java RPC框架,可以和Spring框架无缝集成,2018年阿里巴巴把这个框架捐献给了apache基金会 什么是RPC? RPC全称为remote procedure call,即远程…

python为字体添加上下标

添加上标:^ 添加下标:_ 举例: import numpy as np import matplotlib.pyplot as pltt np.linspace(0, 10, 1000) y np.sin(t) plt.plot(t, y) plt.xlabel(a/${m_2}$,fontdict{weight: normal, size: 15}) plt.show() 效果: …

微信演进的六点思考:微信生态如何演变?如何在其中掘金?

*头图来源:东方IC来源:虎嗅APP虎嗅注:在微信上下游诞生了无数的生态企业,他们关注着微信的一举一动,以便在其中掘金。6月15日,微盟集团CEO孙涛勇在华映资本WE来大会上,分享了对微信生态商业进化…

Day Two(Beta)

站立式会议 站立式会议内容总结 331 今天:指导队友学会xml布局及简单动画,解决了关于中文链接过滤器不能将iso编码改为utf8的情况(修改servletContainer默认编码) 遇到的问题:无 明天:闹钟简单实现,完善方法待解决442 今天:书籍评…

新技术“红”不过十年,半监督学习为什么是个例外?

来源 | 转载自知乎这一波深度学习的发展,以2006年Hinton发表Deep Belief Networks的论文为起点,到今年已经超过了10年。从过往学术界和产业界对新技术的追捧周期,超过10年的是极少数。从深度学习所属的机器学习领域来看,到底什么样…

word空格显示小点

那是因为不小心点了显示隐藏标记,取消即可

《细胞》重磅连发:记忆可“遗传”!

来源:偷鸡捕虾摸螺蛳有人说,记忆到最后也许是最宝贵的财富。人们总是希望能够把最珍视、最有价值的记忆保留下来。科学家们也正为此孜孜不倦的努力着。在2016年的SXSW大会上,南加州大学教授Theodore Berger宣布了一个轰动整个科技界的消息&am…

单词搭配用法查询网站

http://www.just-the-word.com/ 例如查询improve单词的搭配

胡小明:城市大脑与人脑不同的数据意识

一、数据应用要区别对待1.2 数据应用比数据收集重要大数据热正在席卷全国,许多地方政府都成立大数据局,统管政府的数据资源并将数据收集摆在第一位,数据应用研究却迟迟跟不上,投资不断增长应用效益却无相应增长,大数据…

输入关键词查询论文例句网站

http://www.scijuyi.com/es/index.php 国人开发的网站,专门针对英语科技论文写作。输入关键词后,以英文例句的形式返回检索结果。它的使用办法和谷歌学术很相似,但是对语料进行了挑选(以英语为母语的语料为主)&#x…

Redis概述以及安装

二、Redis概述以及安装 Redis是一个开源的key-value存储系统;和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset&#…

宜宾地震,这个系统跑赢了“地震波”!

来源:新华社、现场云、成都高新减灾研究所编辑:关开亮、李永锡、丁鹏程据中国地震台网正式测定:6月17日22时55分,四川省宜宾市长宁县(北纬28.34度,东经104.90度)发生6.0级地震,震源深…

环境变量的作用(以java指令为例)

在很多地方都会涉及到环境变量的概念,这边稍微记录一下笔记。 一、环境变量的分类 Windows中有两种环境变量:用户变量 和 系统变量,它们的区别和作用如下所示: 环境变量不区分大小写;系统变量对所有用户有效&#x…

一文看懂机器视觉芯片

来源:半导体行业观察来源:半导体行业观察【导读】机器视觉之于人工智能等同于视觉之于人类,本文系统介绍决定机器视觉的两大要素——视觉算法和芯片,重点介绍国内外视觉芯片市场及发展前景,包括重量级玩家及其产品。机…

单词短语搭配用法网站

https://linggle.com/? 通配符:*(星号,英文半角)通配一个单词;_(下划线,英文半角)通配多个单词。 例如,搜索in this paper we _(注意星号前需要有空格&…