Java 序列化

【java】java序列化、ArrayList序列化、序列化策略 1、如果一个类想被序列化,需要实现Serializable接口。否则将抛出异常,这是因为,在序列化操作过程中会对类型进行检查,要求被序列化的类必须属于Enum、Array和Serializable类型其中的任何一种。2、在变量声明前加上该关键字,可以阻止该变量被序列化到文件中。3、在类中增加writeObject 和 readObject 方法可以实现自定义序列化策略。 阅读详情

Java 序列化


标记接口

 public interface Serializable{}

正如你看到的,序列化就是这么简单,这个简单的外观,却隐藏着巨大的知识点

什么是序列化

Java的”对象序列化”能让你将一个实现了Serializable接口的对象转换成byte流,这样日后要用这个对象时候,你就能把这些byte数据恢复出来,并据此重新构建那个对象了。

为什么要序列化

简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

什么情况下需要序列化

  • 当你想把的内存中的对象保存到一个文件中或者数据库中时候;
  • 当你想用套接字在网络上传送对象的时候;
  • 当你想通过RMI传输对象的时候;
  • Android中通过Intent传递数据的时候;

序列化发生了什么

  • Make a FileOutputStream
FileOutputStream fs = new FileOutputStream("foo.ser");
  • Make a ObjectOutputStream
ObjectOutputStream os = new ObjectOutputStream(fs);
  • Write the object
os.writeObject(myObject1);
  • Close the ObjectOutputStream
os.close();
Foo myFoo = new Foo();
myFoo .setWidth(37);
myFoo.setHeight(70);

当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对象。

要想序列化对象,你必须先创建一个OutputStream,然后把它嵌进ObjectOutputStream。这时,你就能用writeObject()方法把对象写入OutputStream了。

writeObject()方法负责写入特定类的对象的状态,以便相应的 readObject()方法可以还原它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。

读的时候,你得把InputStream嵌到ObjectInputStream里面,然后再调用readObject()方法。不过这样读出来的,只是一个Object的reference,因此在用之前,还得先下传。readObject() 方法负责从流中读取并还原类字段。它可以调用 in.defaultReadObject 来调用默认机制,以还原对象的非静态和非瞬态字段。  defaultReadObject()方法使用流中的信息来分配流中通过当前对象中相应命名字段保存的对象的字段。这用于处理类发展后需要添加新字段的情形。该方法本身不需要涉及属于其超类或子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。

Demo

public class Box implements Serializable {
    private static final long serialVersionUID = -3450064362986273896L;

    private int width;
    private int height;

    public static void main(String[] args) {
        Box myBox=new Box();
        myBox.setWidth(50);
        myBox.setHeight(30);
        try {
            FileOutputStream fs=new FileOutputStream("F:\\foo.ser");
            ObjectOutputStream os=new ObjectOutputStream(fs);
            os.writeObject(myBox);
            os.close();
            FileInputStream fi=new FileInputStream("F:\\foo.ser");
            ObjectInputStream oi=new ObjectInputStream(fi);
            Box box=(Box)oi.readObject();
            oi.close();
            System.out.println(box.height+","+box.width);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
}

为什么有些类不会序列化

  • 安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输 等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
  • 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且,也是没有必要这样实现。

注意事项

  • 当一个对象被序列化时,只保存对象的非静态成员变量(包括声明为private的变量),不能保存任何的成员方法和静态的成员变量。
  • 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被序列化。
  • 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。
  • 当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
  • 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

serialVersionUID

序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 “serialVersionUID” 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:

 ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 – serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。

此篇博文参考并修改自:http://www.cnblogs.com/gw811/archive/2012/10/10/2718331.html

SAP中寄售结算规则及要点分析 在做MRKO寄售结算时,系统会根据选定的期间和供应商等条件,将符合条件的寄售消耗或寄售上线的物料凭证找出。然后以供应商为单位。合并产生一张会计凭证。下图显示了通过MRKO结算后自动生成的会计凭证。 那么,在MRKO做寄售结算的规则是什么样的?做为寄售业务处理者的物流和财务需要掌握和了解哪些关于寄售结算的规则和控制逻辑。下面以笔者的经验分析一下: 1、寄售物料在系统中有两种处理方法,一种是通过MB1B 411 K ,通常该操作达到两个目的:将物料从仓库转移到线边库(表示即将要投入生产了)的同时将寄售库 阅读详情

相关推荐

ST7789P3初始化配置

【代码】ST7789P3初始化配置。

zqq_1314的博客 4153

mfc获取计算机名和用户名

两个函数搞定GetComputerName();和GetUserName();函数原型:BOOL WINAPI GetComputerName( __out LPTSTR lpBuffer, __inout LPDWORD lpnSize );BOOL WINAPI GetUserName( __out LPTSTR lpBuffer, __inout LPDWOR...

西北攻城狮的博客 3241

重塑计算的五层蛋糕:解读黄仁勋CES2026演讲背后的AI新秩序与物理世界

2026年CES演讲揭示AI新纪元:从语言模型到物理智能 NVIDIA CEO黄仁勋在2026年CES演讲中描绘了计算产业的根本性变革。核心突破包括: 计算范式转移:从指令执行转向意图理解,智能体系统崛起 物理AI突破:发布Cosmos世界模型,通过合成数据训练AI理解物理定律 全新VeraRubin计算平台:6芯片协同设计,解决摩尔定律放缓与AI需求增长的矛盾 自动驾驶革命:推出具备推理能力的Alpamayo模型,实现L4级自动驾驶 演讲标志着AI正从数字世界迈向物理世界,NVIDIA通过全栈布局,正在重

老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 1274

WindowsAPI使用详解——GetComputerName|GetUserName 获取电脑名称和当前用户名

WindowsAPI使用详解——GetComputerName|GetUserName 获取电脑名称和当前用户名 - [VC++编程]版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://flyxxtt.blogbus.com/logs/42725959.html获取电脑的名称,下面是函数的原: BOOL GetComputerName(LPWSTR lpBuffer,

咖啡屋 1万+

DSP28335 ADC模块实战:从寄存器配置到精准数据采集(附代码详解)

本文详细解析DSP28335的ADC模块配置与数据采集实战,涵盖寄存器设置、采样窗口优化、中断处理及代码实现。重点解决ADC精度问题,如采样窗口不足导致数据偏差,提供完整代码示例和调试技巧,助力工程师实现精准数据采集。

kkk56的博客 864

风力发电机并网模型建立及仿真验证

传统能源日益匮乏,环境污染日趋严重,全球向安全、可靠和环保的可持续能源体系转型迫在眉睫,风电迎来了重要的发展契机。近年来,全球风电迅猛发展,我国已成为世界风电新增装机容量第一的国家。然而,随着风电规模的不断增大,风电场接入对系统影响不容忽视。随着变速恒频风力发电系统优越的性能突出和大容量电力电子技术的成熟,风速随机性引起的功率波动及故障情况下的动态响应,对电能质量,系统电压、频率的稳定性产生的影响需要深入研究。因而,本文结合实际项目,针对变速恒频风力发电系统建模,端口动态特性及对电网电能质量、运行稳定性的影

毕业设计区博客 1639

Windows API一日一练(72)GetUserName函数

随着系统安全性的加强,每个系统里越来越多不同的帐号登录。假如你正在开发一个上网安全软件,让不同的用户有不同的上网权限,这样就需要识别当前的用户是什么帐号登录了,然后再作出权限分配。还有出错时,也需要对当前帐号进行记录下来,因为不同的帐号有不同的权限,有些磁盘是不允许操作的。面对这些需求,就需要使用函数GetUserName。 函数GetUserName声明如下: WINA...

anjichan4261的博客 464

树莓派5安装ROS2小白指南避坑攻略

手把手教你如何在树莓派5上顺利安装ROS2,避开常见问题与陷阱,提升配置效率。针对树莓派5安装ros2过程中的依赖冲突、源配置错误等高频难题提供解决方案,适合新手快速上手。

weixin_35754962的博客 1005

VC 得到计算机名和用户名 GetComputerName GetUserName

VC 得到计算机名和用户名 GetComputerName GetUserName

weixin_43417960的博客 675

技术面试官视角:复盘北航/中科院/哈工大保研机试与面试,他们到底在考察什么?(附真题回忆与评分侧重点)

本文从技术面试官视角解析北航、中科院、哈工大等顶尖院校保研机试与面试的考核逻辑,揭示编程语言限制、题目难度设计等隐藏考察维度,并提供真题回忆与评分侧重点。帮助考生理解面试官的真实意图,掌握应对策略,提升通过率。

weixin_42549496的博客 518

【Unity】Gif图片播放插件(支持UI及模型纹理渲染两种模式)

unity本身不支持GIF格式文件直接渲染, 因此一般的做法是通过加载图片,通过代码控制其循环播放、停止等,模拟动画效果,本文简单介绍一下某个现有开源工具,感谢开源作者。

灵境引路人 4036

C++ GetUserName()

关于函数“GetUserName()”,参见:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx IDE: Code::Blocks 操作系统:Windows 7 x64 1 #include <windows.h> 2 #include <stdio...

weixin_34288121的博客 1276

Python 爬虫实战:抓取应届生求职网校招岗位信息,助力学子就业

应届生求职网作为国内知名的招聘平台,汇聚了大量企业的校招岗位信息。了解这些岗位信息,对于应届毕业生制定求职策略、企业制定招聘计划以及相关就业市场分析等都具有重要意义。因此,本文将深入探讨如何运用 Python 爬虫技术从应届生求职网平台抓取校招岗位信息,为应届毕业生提供有益的就业信息支持。本文深入探究了利用 Python 爬虫技术从应届生求职网平台抓取校招岗位信息的全流程。从前期的环境搭建、模拟登录,到核心的数据抓取、存储,再到后续的数据分析与可视化,都详细展开讲解并提供代码支持。

u014481728的博客 1300

java之序列化与反序列化

序列化与反序列化的理解

m0_73866527的博客 1683

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java中的序列化及序列化ID

参考转载自: 秒懂Java序列化与反序列化 Java的序列化ID的作用 1. 定义 Java的序列化:是指把Java对象转换为字节序列的过程 Java的反序列化:是指把字节序列恢复为Java对象的过程 2. 为什么需要 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,.

三明治文鱼的博客 5841

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【Java】Java序列化和反序列化

为了序列化对象,我们调用ObjectOutputStream类的writeObject()方法,而为了反序列化,则调用ObjectInputStream类的readObject()方法。SerializeISA类已序列化扩展了Person类的Student类对象,而Person类是可序列化的。序列化和反序列化过程是平台无关的,这意味着您可以在一个平台上对对象进行序列化,在另一个平台上进行反序列化。现在,id将不会序列化,因此在序列化之后反序列化对象时,您将不会得到id的值。它是序列化的逆操作。

double222222的博客 1142

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

什么是Java序列化,如何实现java序列化

序列化解释: 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。   序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的, 然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(...

qq_38087131的博客 652

从Java序列化到Hadoop序列化

一个原生的类讲解一下,自定义比较器讲解一下,内部类讲解一下。WritableComparator是 WritableComparables的比较器。这个基础实现类使用是自然的排序规则,如果要使用其他的排序规则,需要重写compare(WritableComparable,WritableComparable)方法。

Jenny19992018的博客 591

什么是java序列化,如何实现java序列化?

序列化:将 Java 对象转换成字节流的过程。 反序列化:将字节流转换成 Java 对象的过程。 当Java 对象需要在网络上传输 或者 持久化存储到文件中时,就需要对 Java 对象进行序列化处理。 序列化的实现:类实现 Serializable 接口,这个接口没有需要实现的方法。实现 Serializable 接口是为了告诉 jvm 这个类的对象可以被序列化。 注意事项: 某个类可...

sinat_35566306的博客 672

java序列化

含义、意义使用场景 序列化:将对象写入到IO流中 反序列化:从IO流中恢复对象 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。 使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:

栋幺栋幺-的博客 1920

Java序列化与反序列化

*序列化(Serialization)**是将对象的状态信息转换为可以存储或传输的形式的过程。在Java中,序列化是将对象转换为字节序列的过程。**反序列化(Deserialization)**是将序列化的字节序列恢复为对象的过程。序列化:对象 → 字节流反序列化:字节流 → 对象通过实现和readObject// 不序列化密码// 自定义序列化// 调用默认序列化// 对密码进行加密后再序列化// 自定义反序列化// 调用默认反序列化// 解密密码。

weixin_74417835的博客 1378

java序列化指的是什么,java的序列化是什么

序列化:指堆内存中的java对象数据,通过某种方式把对存储到磁盘文件中,或者传递给其他网络节点(网络传输)。这个过程称为序列化,通常是指将数据结构或对象转化成二进制的过程。 (推荐学习:java课程)即将对象转化为二进制,用于保存,或者网络传输。序列化的作用① 想把内存中的对象保存到一个文件中或者数据库中时候;② 想用套接字在网络上传送对象的时候;③ 想通过RMI传输...

weixin_39820226的博客 2019
上一篇: JavaScript 闭包初步
下一篇: Java 并发编程框架(二)
linroidh
博客等级 码龄16年 15粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值