Java 日看一类(37)之IO包中的ObjectStreamField类

【java】ObjectStreamClass:监视Java对象的序列化 与 ObjectStreamField 1.概述 本文参考了文章:ObjectStreamClass:监视Java对象的序列化 ObjectStreamClass可以是有用的类,用于分析JVM中加载的序列化类的序列化特征。 这篇文章介绍了此类提供的有关已加载序列化类的一些信息。 ObjectStreamClass提供了两个用于查找类的静态方法: lookup(class)和lookupAny(Class) 。 第一个lookup(Class)仅在提供的类可序列化时返回ObjectStreamClass的实例,如果提供的类不可序列化则返回nul. 阅读详情

该类完成了Comparable<Object>接口

引入了

import java.lang.reflect.Field;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;



该类的类头注释如下:

/**
 * A description of a Serializable field from a Serializable class.  An array
 * of ObjectStreamFields is used to declare the Serializable fields of a class.
 *
 * @author      Mike Warres
 * @author      Roger Riggs
 * @see ObjectStreamClass
 * @since 1.2
 */

大意如下:

该类是描述串行化类中串行化字段的类

一般会用一个ObjectStreamField数组来声明一个类中的串行化字段



该类含有如下的成员变量:

字段名称

private final String name;

字段数据类型的JVM签字(基础数据类型标识)

private final String signature;

字段数据类型

private final Class<?> type;

是否将序列化字段值设置为非共享

private final boolean unshared;

字段相应的映射(如果存在才会被赋值)

private final Field field;

封闭字段偏移量

private int offset = 0;



该类含有如下的成员方法:

构造函数(传入字段名和字段数据类型,默认可共享)

public ObjectStreamField(String name, Class<?> type) {
    this(name, type, false);
}

构造函数(传入数据名、数据类型、共享权限)

public ObjectStreamField(String name, Class<?> type, boolean unshared) {
    if (name == null) {
        throw new NullPointerException();
    }
    this.name = name;
    this.type = type;
    this.unshared = unshared;
    signature = getClassSignature(type).intern();//获得传入数据类型的JVM签名
    field = null;
}

构造函数(default类型的,传入的是签名而不是类型)

ObjectStreamField(String name, String signature, boolean unshared) {
    if (name == null) {
        throw new NullPointerException();
    }
    this.name = name;
    this.signature = signature.intern();//返回字符串的规范形式
    this.unshared = unshared;
    field = null;

    switch (signature.charAt(0)) {//根据类型签名获得数据类型
        case 'Z': type = Boolean.TYPE; break;
        case 'B': type = Byte.TYPE; break;
        case 'C': type = Character.TYPE; break;
        case 'S': type = Short.TYPE; break;
        case 'I': type = Integer.TYPE; break;
        case 'J': type = Long.TYPE; break;
        case 'F': type = Float.TYPE; break;
        case 'D': type = Double.TYPE; break;
        case 'L':
        case '[': type = Object.class; break;
        default: throw new IllegalArgumentException("illegal signature");
    }
}

构造函数(给予映射的字段,是否共享控制,对getType()方法返回值的控制(返回实际类型或基础类型,或者是class类))

ObjectStreamField(Field field, boolean unshared, boolean showType) {
    this.field = field;//绑定映射字段
    this.unshared = unshared;
    name = field.getName();//获得字段名称
    Class<?> ftype = field.getType();//字段类型
    type = (showType || ftype.isPrimitive()) ? ftype : Object.class;//如果该类的展示类型为真或者字段类型为基础类型则将字段类型绑定到type 上,否则绑定Object.class
    signature = getClassSignature(ftype).intern();//获得该类的签名
}

获得字段名称

public String getName() {
    return name;
}

获得字段类型

@CallerSensitive
public Class<?> getType() {
    if (System.getSecurityManager() != null) {//获得控制台安全管理器
        Class<?> caller = Reflection.getCallerClass();//获得调用映像,native函数,看不到默认的调用类型
        if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {//判定两个类型的ClassLoader是否相等或者为祖先关系(caller为type的祖先)
            ReflectUtil.checkPackageAccess(type);//如果该类型调用不可访问的包则抛出SecurityException
        }
    }
    return type;
}

获得类型标识符

public char getTypeCode() {
    return signature.charAt(0);//签名中的第一位字符就可以分辨签名类型,所以返回一个即可
}

获得类型的字符串

public String getTypeString() {
    return isPrimitive() ? null : signature;//如果是基础类型就不返回,非基础类型返回类型签名
}

返回字段偏移量

public int getOffset() {
    return offset;
}

设置字段偏移量

protected void setOffset(int offset) {
    this.offset = offset;
}

判定类型是否为基础类型

public boolean isPrimitive() {
    char tcode = signature.charAt(0);
    return ((tcode != 'L') && (tcode != '['));//对应关系可见上面的构造函数,或见下面的签字获取函数
}

返回是否不可共享

public boolean isUnshared() {
    return unshared;
}

字段名称比较

public int compareTo(Object obj) {
    ObjectStreamField other = (ObjectStreamField) obj;//获得传入对象的流字段
    boolean isPrim = isPrimitive();
    if (isPrim != other.isPrimitive()) {//如果两个不全为基础类型或非基础类型
        return isPrim ? -1 : 1;//如果当前值为基础类型则返回-1(对应传入值为非基础),非基础类型则返回1(对应传入值为基础)
    }
    return name.compareTo(other.name);//两个类型全为基础或非基础,按照字典序比较两个字段的名字
}

返回标准的字段描述

public String toString() {
    return signature + ' ' + name;
}

返回该字段的字段类型映射(可能为空,如果没有绑定映射的话)

Field getField() {
    return field;
}

返回类型签字

String getSignature() {
    return signature;
}

获得字段签字

private static String getClassSignature(Class<?> cl) {
    StringBuilder sbuf = new StringBuilder();//类似StingBuffer,可以理解为阉割版的,执行效率比StringBuffer高
    while (cl.isArray()) {//判定传入是否是个数组
        sbuf.append('[');//如果是就写入[
        cl = cl.getComponentType();//返回该数组的类型
    }
    if (cl.isPrimitive()) {//如果是基础类型
        if (cl == Integer.TYPE) {
            sbuf.append('I');
        } else if (cl == Byte.TYPE) {
            sbuf.append('B');
        } else if (cl == Long.TYPE) {
            sbuf.append('J');
        } else if (cl == Float.TYPE) {
            sbuf.append('F');
        } else if (cl == Double.TYPE) {
            sbuf.append('D');
        } else if (cl == Short.TYPE) {
            sbuf.append('S');
        } else if (cl == Character.TYPE) {
            sbuf.append('C');
        } else if (cl == Boolean.TYPE) {
            sbuf.append('Z');
        } else if (cl == Void.TYPE) {
            sbuf.append('V');
        } else {
            throw new InternalError();//内部错误,一般是被其他线程修改了
        }
    } else {//非基础类型,添加如下数据
        sbuf.append('L' + cl.getName().replace('.', '/') + ';');
    }
    return sbuf.toString();//返回标准化后的类型签字
}



该类属于‘常用类’(在封装好的Object操作类中大量使用该类),该类实质上是类字段的一种抽象化表现,但同时也和Field类有所不同,由于该类单纯针对串行化字段,所以提供的功能和属性少于Field类,属于一种更高层次的单一功能性抽象。

Python自动化:3分钟搞定微信收藏链接批量导出到TXT(附完整代码) 本文介绍如何使用Python自动化工具在3分钟内将微信收藏链接批量导出到TXT文件。通过模拟人类操作和OCR技术,脚本高效处理大量链接,显著提升工作效率,并附有完整代码和实战避坑指南。 阅读详情

相关推荐

IVP 2021 UNETR: Transformers for 3D Medical Image Segmentation

动机 具有跟踪和扩展路径的全卷积神经网络(FCNNs)(如编码器和解码器),近年来在各种医学图像分割应用中显示出了突出的地位。在这些体系结构中,编码器通过学习全局上下文表示来扮演一个不可或缺的角色,该全局上下文表示将进一步用于解码器的语义输出预测。 卷积层作为FCNN的主要构造块,其局部性限制了此类网络学习长时空间依赖的能力。 在NLP领域,基于transformer的模型已经在各种任务中实现了最先进的基准。transformer中的自我注意机制使他们能够动态地突出词序列的重要特征并学习其长时依赖关系。这

smile909的博客 1979

java filed_Java ObjectStreamFiled

Java ObjectStreamFiled1 什么是Java ObjectStreamFiledObjectStreamFiled 类是可序列化字段来自Serializable类的描述。 ObjectStreamFields数组用来声明一个类的序列化字段。2Java ObjectStreamFiled的构造方法构造方法描述ObjectStreamField(String name, Class...

weixin_35805266的博客 383

CamoFox MCP:让AI助手隐身操作浏览器的反检测自动化实战

浏览器自动化是提升工作效率和实现数据采集的关键技术,其核心原理在于通过程序脚本模拟人类在网页上的交互行为。传统方案如Selenium或Playwright虽功能强大,但需要开发者编写复杂脚本并处理反爬机制。随着AI Agent技术的发展,自然语言驱动的自动化成为新趋势,它能将任务规划与逻辑判断交由AI处理,大幅降低使用门槛。Model Context Protocol(MCP)作为连接AI与外部工具的标准协议,在此场景下价值凸显,它使得AI助手能直接调用丰富的浏览器操作工具。CamoFox MCP创新性地将

weixin_42551967的博客 729

(每日持续更新)jdk api之ObjectStreamField基础、应用、实战

表示布尔类型的字段。: 表示字节类型的字段。: 表示字符类型的字段。: 表示短整型类型的字段。: 表示整型类型的字段。: 表示长整型类型的字段。: 表示浮点型类型的字段。: 表示双精度浮点型类型的字段。: 表示对象类型的字段。: 表示数组类型的字段。: 返回字段的名称。Class

a89879193的专栏 780

YOLOv8模型RKNN量化策略与RK3588部署实战解析

本文详细解析了YOLOv8模型在RK3588平台上的RKNN量化策略与部署实践。通过对比INT8和FP16量化方式的性能差异,结合实际测试数据,为开发者提供了从模型导出、转换到板端部署的完整解决方案,帮助实现高效的边缘AI应用部署。

oil88的博客 1110

微信文件自动归档!手把手教你用OpenClaw搭个自己的“数字员工”,告别重复劳动

很多人说“AI是未来”,但未来不是靠喊口号的。OpenClaw的真正价值,是让你把重复劳动交出去,把时间留给真正需要创造力的事。这事真能干,而且不难。下载OpenClaw(GitHub仓库按我写的步骤跑一遍遇到坑,评论区留言——我亲自帮你看作者后记:上周五,我让AI自动归档了文件后,终于在5点准时下班。回家路上,我给它发了条消息:“干得漂亮”。它没回,但我知道——它在默默等我的下一条指令。

2601_94871597的博客 415

Java 学习笔记 - IO篇:对象流 ObjectInputStream、ObjectOutputStream

privateStringname="笨笨";}//序列化}catch(IOExceptione){//反序列化}catch(Exceptione){}}}MyObject(name=笨笨,age=18)

灵台方寸山斜月三星洞 704

YOLOv11改进策略【SPPF】| AIFI : 基于Transformer的尺度内特征交互,在降低计算成本的同时提高模型的性能

本文记录的是基于AIFI模块的YOLOv11目标检测改进方法研究。AIFI是RT-DETR中高效混合编码器的一部分,利用其改进YOLOv11模型,

Limiiiing的博客 2241

Java ObjectStreamField isPrimitive()方法与示例

ObjectStreamField类isPrimitive()方法 (ObjectStreamField Class isPrimitive() method) isPrimitive() method is available in java.io package. isPrimitive()方法在java.io包中可用。 isPrimitive() method is used to che...

cumt30111的博客 398

YoloV8改进策略:基于双层路由注意力的视觉Transformer提升YoloV8的检测能力

本文使用2023年最新提出的BiFormer,实现对YoloV8的改进。目前,BiFormer还有在显存占用,还有性能存在问题。我们先试试效果,期待作者在Pytoch上早日实现优化。论文链接:https://arxiv.org/abs/2303.08810代码链接:https://github.com/rayleizhu/BiFormer作为视觉transformer的核心构建模块,注意力是捕捉长程依赖关系的强大工具。

m0_47867638的博客 2845

人形机器人硬件电路设计入门

人形机器人属于。

blotemj.blog.youkuaiyun.com 233

java序列化的实际作用,Java实现序列化的作用和目的

1 package model;23 import java.io.ObjectStreamField;4 import java.io.Serializable;56 /**7 * @author liangd8 * date 2020-11-12 16:169 * code 实例化字段10 */11 public class UserModel implements Serializa...

weixin_33573700的博客 244

点云统计滤波 (python详细过程版)【2025最新版】

统计滤波python详细过程版,博客长期更新,本文最近更新时间为:2025年1月12日。

点云侠的博客 5639

Java多种方式自定义序列化

我们知道,通过实现java.io.Serializable接口可以使得该类的实例能够被序列化。例如如下的Person类, import java.io.Serializable; public class Person implements Serializable { private String name; private int age; public P

Genge 4192

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

java serializable 源码_Java 序列化和反序列化(三)Serializable 源码分析 - 2

Java 序列化和反序列化(三)Serializable 源码分析 - 2在上一篇文章中围绕 ObjectOutputStream#writeObject 讲解了一下序列化的整个流程,这中间很多地方涉及到了 ObjectStreamClass 和 ObjectStreamField 这两个类。ObjectStreamField 按官方的说法是是字段的序列化描述符,本质是对 Field 字段的包装,...

weixin_39546501的博客 272

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java ObjectStreamField getType()方法与示例

ObjectStreamField类的getType()方法 (ObjectStreamField Class getType() method) getType() method is available in java.io package. getType()方法在java.io包中可用。 getType() method is used to get the type of this O...

cumtv80668的专栏 1598

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java ObjectStreamField getName()方法与示例

ObjectStreamField类的getName()方法 (ObjectStreamField Class getName() method) getName() method is available in java.io package. getName()方法在java.io包中可用。 getName() method is used to get the name of this O...

cumtb2002的博客 1053

java-ObjectStream初步认识

import java.io.*; class ObjectStreamDemo {  public static void main(String[] args) throws Exception, IOException, ClassNotFoundException  {   setObjectStream();   getObjSetStream();  }  public static

用十年代码经验,替你踩平AI落地的坑。 2564

Java ObjectStreamField toString()方法与示例

ObjectStreamField类toString()方法 (ObjectStreamField Class toString() method) toString() method is available in java.io package. toString()方法在java.io包中可用。 toString() method is used to return a string th...

cumtb2002的博客 432

Java ObjectStreamField compareTo()方法与示例

ObjectStreamField类compareTo()方法 (ObjectStreamField Class compareTo() method) compareTo() method is available in java.io package. compareTo()方法在java.io包中可用。 compareTo() method is used to compare thi...

cumt30111的博客 452

20.Java序列化【草案二】

(从09年回到重庆过后,就一直在工作,时间长了惰性就慢慢起来了,公司的项目从09年忙到了现在,一直没有时间来梳理自己的东西,优快云的Blog似乎都荒废了,不知道现在还能否坚持把Blog完成,希望有一个新的开始吧!如果读者有问题还是可直接发邮件到silentbalanceyh@126.com,我也仅仅只是想把看的、写的、学的东西总结起来,让自己有个比较完整的学习记录。本文主要针对Java的序列化相

风中的索莉逖亚 7064

【Java杂记】序列化:从Java序列化到多种序列化方式

1.序列化是什么 Java平台允许我们创建对象 但是只有当JVM运行时,这些对象才存在,也就是说对象的声明周期不回避JVM的生命周期长 但我们在硬盘上存储对象,或者通过网络传输对象的时候已经脱离了JVM,已经不是java对象了 ==> 需要一种方式:Java对象 —序列化–> 保存/传输 –反序列化–> Java对象 序列化(编码): 把对象的状态信息转化为可存储或传输的形式过程,也就是把对象转化为字节序列的过程 Java对象 –编码协议–> 字节/符序列 反序列化(解码

A minor 3012

对象序列化

序列化 反序列化 使用Externalizable接口

我叫王哈哈 831

ObjectStream

例:将Employee对象及数组对象存储在文件中,再读出. 其中age属性不需要序列化 /* * 需要序列化的对象必须实现Serializable接口(空接口) * 若其中存在不想序列化的属性,加transient关键字 */ public class Employee implements Serializable{ private String name; private tra...

sinat_41627479的博客 783

【JDK源码分析】01-对象序列化ObjectOutputStream

上一篇文章提到反序列化枚举类仍是单例,而普通类对象不是单例,下面我们先分析一下序列化过程,序列化就是调用ObjectOutStream的对象的writeObject方法。我们先看一下序列化涉及的比较重要的一个ObjectStreamClass,JDK中的描述是:类的序列化描述符。它包含类描述信息,字段的描述信息和 serialVersionUID。可以使用 lookup 方法找到/创建在此 Jav...

通往神秘的道路的专栏 1426

hashmap冲突的解决方法以及原理分析:

在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例: HashMap<String,Object> m=new HashMap<String,Object>();m.put("a", "rrr1...

weixin_30813225的博客 5367
上一篇: Java 日看一类(36)之IO包中的ObjectInputVaildation接口和ObjectOutput接口
下一篇: Java 日看一类(38)之IO包中的ObjectStreamConstant类
wyf95278
博客等级 码龄10年 38粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值