由浅到深认识Java语言(38):I/O流

该文章Github地址:https://github.com/AntonyCheng/java-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Java语言(37):I/O流

44.I/O流(操作文件中的数据)

对象的序列化

对象序列化:简单来说就是用 IO 流技术把对象写入(ObjectOutputStream 类)文件,反之,从文件中读取(ObjectInputStream 类)一个对象就是对象的反序列化,==所以先要做序列化,才能做反序列化,这两个类依然是"装饰者";==

**开启对象序列化:**每一个普通类是没有序列化权限的,必须要实现 Serializable 接口以启用序列化;

**对象的序列化意义:**把对象变成一个文件,允许这个对象文件在网络上传输,可以让任何人使用;

JavaBeans

概念

JavaBeans是 Java 中一种特殊的类,可以将多个对象封装到一个对象(bean)中。特点是可序列化,提供无参构造器,提供 getter 方法和 setter 方法访问对象的属性。名称中的“Bean”是用于Java的可重用软件组件的惯用叫法。

优点
  • Bean可以控制它的属性、事件和方法是否暴露给其他程序。
  • Bean可以接收来自其他对象的事件,也可以产生事件给其他对象。
  • 有软件可用来配置Bean。
  • Bean的属性可以被序列化,以供日后重用。
规范

要成为 JavaBean 类别,则必需遵循关于命名、构造器、方法的特定规范。有了这些规范,才能有可以使用、复用、替代和连接 JavaBeans 的工具。

规范如下:

  • 变量私有化。
  • 有一个public的无参数构造函数。
  • 属性可以透过getsetis(可替代get,用在布尔型属性上)方法或遵循特定命名规则的其他方法访问。
  • 可序列化。
package player;

public class PersonBean implements java.io.Serializable {

    /**
     * name 属性(注意大小写)
     */
    private String name = null;

    private boolean deceased = false;

    /** 无参构造器 */
    public PersonBean() {
    }

    /**
     * name 属性的 Getter方法
     */
    public String getName() {
        return name;
    }

    /**
     * name 属性的Setter方法
     * @param value
     */
    public void setName(final String value) {
        name = value;
    }

    /**
     * deceased 属性的Getter方法
     * 布林值属性Getter方法的不同形式(这里使用了is而非get)
     */
    public boolean isDeceased() {
        return deceased;
    }

    /**
     * deceased 属性的Setter方法
     * @param value
     */
    public void setDeceased(final boolean value) {
        deceased = value;
    }
}

ObjectOutputStream 对象的序列化

  • 构造方法 ObjectOutputStream(OutputStream out) 传递字节输出流;
  • 方法 void writeObject(Object o) 写入对象;

示例如下:

package top.sharehome.Demo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Demo {

    public static void main(String[] args) {
        Person p = new Person("张三",21);
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(p);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ObjectInputStream 对象的反序列化

  • 构造方法 ObjectInputStream(InputStream in) 传递字节输入流;
  • 方法 Object readObject() 读取对象,由于得到的是 Object 对象,所以读取到对象后还需要进行对象的强制转换;

示例如下:

package top.sharehome.Demo;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class Demo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            ois = new ObjectInputStream(fis);
            Object obj = ois.readObject();
            System.out.println(obj.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不能序列化的情况

静态属性:

类中的静态成员也成为实例实例,实例成员是属于类本身的,随着类的加载而加载,而我们创建的是对象,做的是对象的序列化,而实例成员并不属于我们所创建的对象,所以静态属性不会被序列化,写入文件的结果是数据类型的默认值;

transient 关键字修饰:

transient 关键字只有一个作用,那就是阻止变量的值被序列化写入文件中;

示例如下:

package top.sharehome.Demo;

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        Person p = new Person("李四",20);
        try {
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            oos = new ObjectOutputStream(fos);
            ois = new ObjectInputStream(fis);
            oos.writeObject(p);
            Object obj = ois.readObject();
            System.out.println(obj.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (oos!=null){
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private transient int 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

静态变量和此种情况的打印效果一模一样;

序列号

固定格式:

static final long serialVersionUID = 42L; //赋值部分可自行修改,即42L可修改;

当我们需要把一个类序列化时,不仅需要让这个类实现 Serializable 接口,还需要在类的成员变量中加入上述格式的序列号;

**序列号目的:**防止写入的文件被篡改,此时序列号就成了这个类的唯一标识;

下一章:由浅到深认识Java语言(39):网络编程

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

寄主机显示器被快递搞坏了怎么办?怎么破?

大家好,我是平泽裕也。 最近,我在社区里看到很多关于开学后弟弟寄来的电脑显示器被快递损坏的帖子。 看到它真的让我感到难过。 如果有人的数码产品被快递损坏了,我会伤心很久。 那么今天就跟大家聊聊寄快递的一些小技巧。 作为一名曾经的…

iptables添加端口映射,k8s主机查询不到端口但能访问。

研究原因:k8s内一台主机使用命令查询没有80端口。但通过浏览器访问又能访问到服务。 查询了资料是使用了hostport方式暴露pod端口。cni调用iptables增加了DNAT规则。访问时流量先经过iptables直接被NAT到具体服务去了。 链接: K8s罪魁祸首之"HostPort劫持了我…

【2024.3.28练习】砝码称重

题目描述 题目分析 动态规划解决。建立状态&#xff0c;数组元素为0或1&#xff0c;代表只用前个砝码能否称出重量。 设个砝码重量为&#xff0c;则第状态转移方程为&#xff1a; 我的代码 #include <iostream> #include <algorithm> #include <cmath> #i…

武汉星起航:五对一服务体系,引领卖家迅速适应亚马逊市场

在数字化浪潮的推动下&#xff0c;亚马逊跨境电商行业成为了众多创业者和企业家们竞相追逐的热门领域。然而&#xff0c;对于零经验的新手卖家而言&#xff0c;这个看似充满机遇的跨境电商世界实则暗藏无数挑战和未知。在这个关键时刻&#xff0c;武汉星起航公司以其专业的服务…

环信IM集成教程---消息转发合并转发的实现

前言 在发送消息体系中&#xff0c;转发消息是一个重要的环节&#xff0c;可以单条转发也可以合并转发。本文教大家在接入环信IM过程中如何实现单条转发&#xff0c;合并转发消息功能&#xff0c;同时举例一些容易踩坑的位置&#xff0c;以便大家尽快顺利的实现转发消息功能。…

Python实现猜数字游戏:一次编程旅程

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

融合创新!全局注意力+局部注意力,训练成本直降91.6%

全局注意力结合局部注意力可以让模型在处理数据时&#xff0c;既不会丢失重要的局部细节&#xff0c;也能考虑到整个数据集中的全局结构&#xff0c;从而在保持模型计算效率的同时&#xff0c;提高模型的表达能力。 这种策略相较于传统的单一注意力机制&#xff0c;能够更全面…

通用指南-营销和设计中的增强现实(AR)

原文作者&#xff1a;Superside 翻译&#xff1a;数字化营销工兵 --- 经典万字长文&#xff0c;权威解读&#xff0c;分享经典&#xff0c;预计阅读完需要30分钟&#xff0c;建议收藏&#xff01; 目录 一、引言 为什么要尝试AR AR到底是什么&#xff1f;营销人员和创意人…

巨控NET400网关:工业通讯的未来之门

描述&#xff1a;在数字化时代&#xff0c;工业通讯作为智能制造的核心&#xff0c;承载着数据交换、设备控制等关键任务。巨控NET400以其独特的优势&#xff0c;为各行各业的智能转型提供了强大的技术支持。本文深入探讨NET400的核心功能与主要优势&#xff0c;展望其在工业通…

T1 神奇苹果桶 (25分) - 小米前端笔试编程题解

考试平台&#xff1a; 赛码 题目类型&#xff1a; 20道选择 2道编程题 考试时间&#xff1a; 2024-03-23 &#xff08;两小时&#xff09; 题目描述 小希在森林冒险的时候发现一个神奇的木桶&#xff0c;某些时会凭空出现一些苹果&#xff0c;小希很解地大家分享了这一个神奇…

Markdown 编辑器使用

CSDN 在博客开头加上 [TOC](你的目录标题)就可以根据博客内容自动生成如下所示的目录&#xff1a; 你的目录标题 Markdown 编辑器功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表无序列表…

1.java openCV4.x 入门-环境搭建

专栏简介 &#x1f492;个人主页 &#x1f4d6;心灵鸡汤&#x1f4d6;大家 &#x1f4f0;专栏目录 点击上方查看更多内容 环境搭建 一、开发环境二、环境搭建1.openCV安装1.下载程序包 2.程序包安装3.搭建项目 三、非必要资源1.扩展库2.cmake 一、开发环境 开发工具 i…

structured bindings is supported from c++17

完整示例&#xff1a; #include <iostream> #include <format> #include <iomanip>void test_00(){struct Box{int width_;int height_;std::string name_;};Box box{3,4,"amazing"};auto [w, h, name]{box};//auto [w, h, name] box;std::cout …

openwrt在校园网环境下开启nat6 (ipv6 nat)

如果将路由器接入校园网&#xff0c;我们只能获得一个128位掩码的ipv6地址。这个地址仅供路由器本身使用&#xff0c;而路由器后的设备无法获取到ipv6地址&#xff0c;因此我们可以利用网络地址转换&#xff08;NAT&#xff09;为这些设备分配本地ipv6地址。 下面是openwrt开启…

TSINGSEE青犀推出县域治理视频基座数字化、智慧化解决方案

一、方案背景 县域治理方案是我国地方治理体系的重要组成部分&#xff0c;对于促进县域经济社会发展、维护社会稳定、推进全面深化改革具有重要意义。随着科技的不断进步&#xff0c;视频监管已经成为了现代社会治理的重要手段之一。县域治理视频监管方案是通过视频监控、数据…

高效 CUDA 调试:将 NVIDIA Compute Sanitizer 与 NVIDIA 工具扩展结合使用并创建自定义工具

高效 CUDA 调试&#xff1a;将 NVIDIA Compute Sanitizer 与 NVIDIA 工具扩展结合使用并创建自定义工具 NVIDIA Compute Sanitizer 是一款功能强大的工具&#xff0c;可以节省您的时间和精力&#xff0c;同时提高 CUDA 应用程序的可靠性和性能。 在 CUDA 环境中调试代码既具有挑…

C#全新一代医院手术麻醉系统围术期全流程源码

目录 一、麻醉学科的起源 二、麻醉前访视与评估记录单 患者基本信息 临床诊断 患者重要器官功能及疾病情况 病人体格情况分级 手术麻醉风险评估 拟施麻醉方法及辅助措施 其他需要说明的情况 访视麻醉医师签名 访视时间 与麻醉相关的检查结果 三、手术麻醉信息系统…

Laravel扩展包的开发

扩展包的开发 1. 创建一个新项目&#xff0c;初始化扩展包配置 首先创建一个全新的Laravel项目&#xff1a; composer create-project --prefer-dist laravel/laravel laravelPkg 接下来&#xff0c;在项目中创建目录package/{your_name}/{your_package_name} mkdir -p pa…

STM32硬件I2C通信外设

文章目录 前言I2C硬件介绍10 位地址模式硬件I2C的引脚定义I2C框图主机发送序列图主机接收序列图 硬件I2C读写MPU6050总结 前言 本文主要介绍stm32自带的I2C通信外设&#xff0c;对比与软件模拟I2C&#xff0c;硬件I2C可以自动生成时序&#xff0c;时序的操作更加及时规范&…
最新文章