Java序列化流有何奇妙之处呢?通过一个个案例逐一感受序列化流。
!!!好戏在后头!!!
1.IO流读写文件
先从一个普通文件读写字符串开始讲起。
例子:输出字符串到文件,再从文件中读取字符串
在某一天 灵感迸发:我可以把Java程序中的 对象信息直接保存到普通的 txt 文件中吗?并且当我想使用它时,还可以拿出来就可以直接用,不需要再做其他处理,就像存储普通的字符串一样,在文件中读出来就可以直接使用的那种。
2.序列化和反序列化流奇妙之处
要想实现对象信息存储到普通文件不被破化,并且读取出来不需要再做其他处理既可以像使用普通new出来的对象一样直接使用的效果,必须有一种 特殊的IO流来完成,于是诞生了 序列化流和反序列化流。
2.1.案例一:把普通文件当作对象存储库来使用
详细的描述:将一个list 集合保存到普通文件,再读出来直接使用,实现list集合数据的增删改查
Person 类
// 序列化对象信息:必须实现序列化标记接口Serializable<br>public class Person implements Serializable {<br>    // 序列化版本UID<br>    private static final long serialVersionUID = 1L;<br>    private String name;<br>    private int age;<br>    private String sex;<br>    public String <span class="hljs-function"><span class="hljs-title">getName</span></span>() {<br>        <span class="hljs-built_in">return</span> name;<br>    }<br>    public void setName(String name) {<br>        this.name = name;<br>    }<br>    public int <span class="hljs-function"><span class="hljs-title">getAge</span></span>() {<br>        <span class="hljs-built_in">return</span> age;<br>    }<br>    public void setAge(int age) {<br>        this.age = age;<br>    }<br>    public String <span class="hljs-function"><span class="hljs-title">getSex</span></span>() {<br>        <span class="hljs-built_in">return</span> sex;<br>    }<br>    public void setSex(String sex) {<br>        this.sex = sex;<br>    }<br><br>    @Override<br>    public String <span class="hljs-function"><span class="hljs-title">toString</span></span>() {<br>        <span class="hljs-built_in">return</span> <span class="hljs-string">"Person{"</span> + <span class="hljs-string">"name='"</span> + name + <span class="hljs-string">", age="</span> + age + <span class="hljs-string">", sex='"</span> + sex + <span class="hljs-string">'}'</span>;<br>    }<br>    public <span class="hljs-function"><span class="hljs-title">Person</span></span>() {<br>    }<br>    public Person(String name, Integer age, String sex) {<br>        this.name = name;<br>        this.age = age;<br>        this.sex = sex;<br>    }<br>}
序列化和反序列化
public class Demo2 {<br>    public static void main(String[] args) throws IOException, ClassNotFoundException {<br>        //数据准备:集合类都实现了序列化接口Serializable<br>        List<person> list = new ArrayList<>();<br>        list.add(new Person(<span class="hljs-string">"张三"</span>,38,<span class="hljs-string">"男"</span>));<br>        list.add(new Person(<span class="hljs-string">"李四"</span>,38,<span class="hljs-string">"男"</span>));<br>        list.add(new Person(<span class="hljs-string">"如花"</span>,18,<span class="hljs-string">"女"</span>));<br><br>        // 序列化保存到普通文件<br>        File file = new File(<span class="hljs-string">"D:/demo2.txt"</span>);<br>        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));<br>        objectOutputStream.writeObject(list);<br>        objectOutputStream.close();<br><br>        // 读取普通文件反序列化<br>        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));<br>        List<person> personList = (List<person>) objectInputStream.readObject();<br>        objectInputStream.close();<br>        <span class="hljs-keyword">for</span> (Person person:personList){<br>            System.out.println(person);<br>        }<br>        <br>    }<br>}<br></person></person></person>
执行结果:
序列化保存到普通文件的数据:
虽然没人会考虑使用这种方式来保存数据,但这对于理解序列化流有很大的帮助。
2.2.案例二:任意元素类型的List 集合序列化读写
**<br> * 任意元素类型的List 集合的对象存储到普通文件,读取直接使用<br> * @param <t><br> */<br>public class ObjectList<t extends list> {<br>    // 序列化保存到普通文件<br>    private File file = new File(<span class="hljs-string">"D:/demoList.txt"</span>);<br><br>    public void writerList(T t) throws IOException {<br>        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));<br>        objectOutputStream.writeObject(t);<br>        objectOutputStream.close();<br>    }<br><br>    public T readList() throws IOException, ClassNotFoundException {<br>        // 读取普通文件反序列化<br>        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));<br>        T t = (T) objectInputStream.readObject();<br>        objectInputStream.close();<br>        <span class="hljs-built_in">return</span> t;<br>    }<br><br>    public boolean <span class="hljs-function"><span class="hljs-title">isExists</span></span>(){<br>        <span class="hljs-built_in">return</span> file.exists();<br>    }<br>    public boolean <span class="hljs-function"><span class="hljs-title">delete</span></span>(){<br>        <span class="hljs-built_in">return</span> file.delete();<br>    }<br><br>    // 测试<br>    public static void main(String[] args) throws IOException, ClassNotFoundException {<br>        ObjectList<list<person>> objectList = new ObjectList<>();<br>        //数据准备:集合类都实现了序列化接口Serializable<br>        List<person> list = new ArrayList<>();<br>        list.add(new Person(<span class="hljs-string">"张三"</span>,38,<span class="hljs-string">"男"</span>));<br>        list.add(new Person(<span class="hljs-string">"李四"</span>,38,<span class="hljs-string">"男"</span>));<br>        list.add(new Person(<span class="hljs-string">"如花"</span>,18,<span class="hljs-string">"女"</span>));<br>        // 持久化对象数据<br>        objectList.writerList(list);<br>        // 查询持久化对象数据<br>        List<person> personList = objectList.readList();<br>        System.out.println(<span class="hljs-string">"遍历持久化对象数据>"</span>);<br>        <span class="hljs-keyword">for</span> (Person person:personList){<br>            System.out.println(person);<br>            <span class="hljs-keyword">if</span> (person.getAge()==38){// 修改年龄38的都改为18<br>                person.setAge(18);<br>            }<br>        }<br>        // 修改后持久化对象数据<br>        objectList.writerList(personList);<br>        System.out.println(<span class="hljs-string">"遍历修改持久化对象数据>"</span>);<br>        List<person> personList1 = objectList.readList();<br>        <span class="hljs-keyword">for</span> (Person person:personList1){<br>            System.out.println(person);<br>        }<br>        // 删除对象存储的持久化文件<br>        <span class="hljs-keyword">if</span> (objectList.isExists()){<br>            System.out.println(<span class="hljs-string">"删除对象存储的持久化文件"</span>);<br>            objectList.delete();<br>        }<br><br>    }<br><br>}<br></person></person></person></list<person></t extends list></t>
序列化的目的
- 序列化流目的:把对象模型数据按序列化规则进行转化,转化后的数据可以保存到磁盘文本或通过网络传输;
- 反序列化流目的:把磁盘文件或网络传输的序列化数据按反序列化规则进行转化,恢复成对象模型数据,在程序中可直接操作对象模型数据。
前面的案例都是程序和磁盘的IO操作,接下来的是序列化对象通过网络传输的案例。
2.3.案例三:自己实现Java RMI(远程方法调用)
Java RMI(Remote Method Invocation)Java 远程方法调用,是Java编程语言里的一种用于实现远程方法调用的应用程序编程接口。RMI的宗旨就是尽可能简化远程接口对象的使用。
相类似的远程过程调用RPC(Remote Procedure Call),指的是一个进程调用另一个进程(本地或远程主机的进程)的过程。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,既提供了分布式对象间的通讯。但Java RMI仅限于Java语言间相互调用,无法实现不同语言间的远程方法调用。
在这感受下怎么实现远程方法调用,好玩时刻来了。
!!!高能预警!!!
篇幅原因,请移步到:自己写了个Java RMI(远程方法调用) 的实现案例 ;
更多优质文章和资源👇
原创不易:分享,点赞👇
Original: https://www.cnblogs.com/dennyLee2025/p/15977942.html
Author: 渊渟岳
Title: Java序列化流的奇妙之旅
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620498/
转载文章受原作者版权保护。转载请注明原作者出处!