hessian和xfire序列化反序列化使用注意

1、hessian

1)序列化

hessian序列化一个对象时,默认的序列化类是com.caucho.hessian.io.JavaSerializer。JavaSerializer的writeObject方法代码片段如下:

try {

      out.writeMapBegin(cl.getName());
      for (int i = 0; i < _fields.length; i++) {
        Field field = _fields[i];
        out.writeString(field.getName());
        out.writeObject(field.get(obj));
      }
      out.writeMapEnd();
    } catch (IllegalAccessException e) {
      throw new IOException(String.valueOf(e));
}

序列化时将属性和属性值都写入到流中,属性_fields是在JavaSerializer的构造函数里初始化的,获取当前Class的所有属性,接着获取父类的所有属性,所有属性都放在一个数组里。

public JavaSerializer(Class cl) {
        _writeReplace = getWriteReplace(cl);
        if (_writeReplace != null) _writeReplace.setAccessible(true);

        ArrayList primitiveFields = new ArrayList();
        ArrayList compoundFields = new ArrayList();
        for (; cl != null; cl = cl.getSuperclass()) {
            Field[] fields = cl.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) continue;
                field.setAccessible(true);
                if (field.getType().isPrimitive() || field.getType().getName().startsWith("java.lang.") && !field.getType().equals(Object.class)) primitiveFields.add(field);
                else compoundFields.add(field);
            }
        }
        ArrayList fields = new ArrayList();
        fields.addAll(primitiveFields);
        fields.addAll(compoundFields);
        _fields = new Field[fields.size()];
        fields.toArray(_fields);
    }

2)反序列化

反序列化的时候,所有属性放在了一个HashMap里,HashMap的key不能重复。这样就有问题,如果子类和父类有同名的字段就会有问题,子类的值会被父类的值覆盖掉,父类的值不会填充。
JavaDeserializer的readObject代码片段如下:从流里面拿出属性名,在_fieldMap中找属性对应的FieldDeserializer。找到后反序列化对象,未找到则从流中跳过当前属性。所以反序列化时双方属性的交集值是准确的,反序列化未找到的属性保持对应类型的默认值。 
 for (int i = 0; i < fieldNames.length; i++) {
        String name = fieldNames[i];
        FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(name);
        if (deser != null)
  deser.deserialize(in, obj);
        else
          in.readObject();
      }
_fieldMap初始化构造属性名到属性反序列化器的映射,先填充类自身属性,后填充父类属性。若子类和父类存在同名属性则使用子类的反序列化器
protected HashMap getFieldMap(Class cl)
{
    HashMap fieldMap = new HashMap();
    for (; cl != null; cl = cl.getSuperclass()) {
      Field []fields = cl.getDeclaredFields();
      for (int i = 0; i < fields.length; i++) {
        Field field = fields[i];
        if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
          continue;
        else if (fieldMap.get(field.getName()) != null)
          continue;
        try {
          field.setAccessible(true);
        } catch (Throwable e) {
          e.printStackTrace();
        }

        fieldMap.put(field.getName(), field);
      }
    }
    return fieldMap;
  }
  
然后根据属性名读取属性值,JavaDeserializer的readMap方法的代码片段
   while (!in.isEnd()) {
            Object key = in.readObject();
            Field field = (Field) _fieldMap.get(key);
            if (field != null) {
                Object value = in.readObject(field.getType());
                try {
                    field.set(obj, value);
                } catch (Throwable e) {
                    IOException e1 = new IOException("Failed setting: " + field + " with " + value + "\n"
                                                     + e.toString());
                    e1.initCause(e);
                    throw e1;
                }
            } else {
                Object value = in.readObject();
            }
        }
序列化的时候所有属性会被按顺序写入,反序列化的时候按照序列化的顺序读取fieldName,在fieldMap中查找对应Field,找到后初始化对象并填充value。这样如果序列化和反序列化时class的属性个数和名称不一致,那反序列化时双方属性的交集值是准确的,反序列化未找到的属性保持对应类型的默认值。
另外对于同名字段,写的时候同名属性先写子类的,再写父类的。读的时候子类的该字段值会被赋值两次,总是被父类的值覆盖,而父类的值是对应类型的默认值。导致子类和父类字段值都丢失。

3)使用注意点:

1)使用hessian序列化时,一定要注意子类和父类不能有同名字段。
2)使用hessian序列化时,待序列化对象必须有默认构造函数。
3)反序列化时可以在序列化流中找的属性被填充,找不到的属性用对应类型的默认值。

Xfire

序列化注意点

1)待序列化类型必须有默认构造函数。
private Constructor<T> getConstructor0(Class[] parameterTypes,int which) throws NoSuchMethodException
{
        Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
        for (int i = 0; i < constructors.length; i++) {
            if (arrayContentsEq(parameterTypes,constructors[i].getParameterTypes())) {
                return getReflectionFactory().copyConstructor(constructors[i]);
            }
        }
        throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
    }

    private HashMap pdStore = new HashMap();

2)属性描述器以Map格式存储,同名属性描述器以List对应Map的一个Key
    /**
     * Adds the property descriptor to the list store.
     */
private void addPropertyDescriptor(PropertyDescriptor pd) {
String propName = pd.getName();
List list = (List)pdStore.get(propName);
if (list == null) {
    list = new ArrayList();
    pdStore.put(propName, list);
}
list.add(pd);
}

//获取类型的属性描述器时将描述器Map转为列表
private PropertyDescriptor[] getTargetPropertyInfo() {
    //....
result = (PropertyDescriptor[])properties.values().toArray(result);
//...
}
3)方法描述器以Map格式存储,同名方法描述器合成后对应Map中一个Key。
String name = md.getName();
MethodDescriptor old = (MethodDescriptor)methods.get(name);
if (old == null) {
   // This is the common case.
   methods.put(name, md);
   return;
}

String[] p1 = md.getParamNames();
String[] p2 = old.getParamNames();

boolean match = false;
if (p1.length == p2.length) {
   match = true;
   for (int i = 0; i < p1.length; i++) {
if (p1[i] != p2[i]) {
    match = false;
    break;
}
    }
}

if (match) {
    MethodDescriptor composite = new MethodDescriptor(old, md);
    methods.put(name, composite);
    return;
}
4)读写属性需要getMethod,setMethod,找不到对应方法会报错
    try
        {
            PropertyDescriptor desc = getTypeInfo().getPropertyDescriptorFromMappedName(name);
            Method m = desc.getReadMethod();
            if (m == null)
                throw new XFireFault("No read method for property " + name + " in class "+ object.getClass().getName(), XFireFault.SENDER);
            return m.invoke(object, new Object[0]);
        }
读方法名初始化
if (type == boolean.class || type == null) {
    readMethodName = "is" + getBaseName();
} else {
    readMethodName = "get" + getBaseName();
}

   // Since there can be multiple write methods but only one getter
   // method, find the getter method first so that you know what the
   // property type is.  For booleans, there can be "is" and "get"
   // methods.  If an "is" method exists, this is the official
   // reader method so look for this one first.
   readMethod = Introspector.findMethod(cls, readMethodName, 0);
   if (readMethod == null) {
readMethodName = "get" + getBaseName();
readMethod = Introspector.findMethod(cls, readMethodName, 0);
   }
写入流程
BeanTypeInfo的属性描述器初始化到element,element到Type,type写入属性
PropertyDescriptor[] descriptors;
initialize()
mapProperty()
mapElement(String property, QName mappedName)
List elements = new ArrayList();

for (Iterator itr = info.getElements(); itr.hasNext();){
            QName name = (QName) itr.next();
            if (info.isExtension()&& info.getPropertyDescriptorFromMappedName(name).getReadMethod().getDeclaringClass() != info.getTypeClass()){
                continue;
            }
            Object value = readProperty(object, name);
            Type type = getType(info, name);
            type = AegisBindingProvider.getWriteType(context, value, type);
            MessageWriter cwriter;
            // Write the value if it is not null.
            if (value != null){
                cwriter = getWriter(writer, name, type);
                if (type == null)
                    throw new XFireRuntimeException("Couldn't find type for " + value.getClass()+ " for property " + name);
                type.writeObject(value, cwriter, context);
                cwriter.close();
            }
读入流程
BeanTypeInfo的属性描述器初始化到attributes,attribute到Type,type读入属性
PropertyDescriptor[] descriptors;
initialize()
mapProperty()
mapAttribute(name, createMappedName(pd));
List attribute = new ArrayList();
   for (Iterator itr = info.getAttributes(); itr.hasNext();){
            QName name = (QName) itr.next();
            Object value = readProperty(object, name);
            if (value != null){
                Type type = getType(info, name);
                if (type == null)
                    throw new XFireRuntimeException("Couldn't find type for " + value.getClass()+ " for property " + name);
                MessageWriter cwriter = writer.getAttributeWriter(name);
                type.writeObject(value, cwriter, context);
                cwriter.close();
            }
        }

反序列化注意点

反序列化时,根据MessageContext中的name在自己的根据自己的BeanType找不到对应Type,跳过这个属性。所以反序列化时拿到的是写入属性(序列化属性集合)和待读属性(反序列化类型属性集合)的交集。剩余属性为类型的默认值。

while (reader.hasMoreElementReaders()) {
            MessageReader childReader = reader.getNextElementReader();
            QName name = childReader.getName();
            BeanType parent = getBeanTypeWithProperty(name);
            Type defaultType = null;
            if (parent != null) {
                info = parent.getTypeInfo();
                defaultType = info.getType(name);
            } else {
                defaultType = null;
            }
            Type type = AegisBindingProvider.getReadType(childReader.getXMLStreamReader(), context,defaultType, getTypeMapping());
            if (type != null) {
                if (!childReader.isXsiNil()) {
                    Object writeObj = type.readObject(childReader, context);
                    if (isProxy) {
                        delegate.writeProperty(name.getLocalPart(), writeObj);
                    } else {
                        writeProperty(name, object, writeObj, clazz, info);
                    }
                }
                //...
            } else {
                childReader.readToEnd();
            }
        }

内容概要:本文提出了一种面向通信优化的微电网分布式二次电压频率调控与功率均分方法,结合Simulink仿真实现,旨在解决微电网中电压频率恢复与有功/无功功率精确分配的关键问题。通过引入混合动态事件触发机制,在确保控制精度的同时显著降低通信频率,有效缓解通信资源紧张问题,提升系统实时性与运行效率。该方法采用完全分布式的协同控制架构,摆脱对中央控制器的依赖,避免单点故障风险,增强系统的鲁棒性与可扩展性。仿真模型构建了包含多个分布式发电单元(DG)的微电网系统,详细模拟其动态响应过程,验证了所提策略在不同负载扰动、通信延迟及网络拓扑变化等复杂工况下的有效性,成功实现了电压频率的快速无静差恢复与功率的精确均分,兼顾了控制性能与通信成本的双重优化。; 适合人群:具备电力系统、自动控制理论或新能源并网技术等相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网控制、分布式能源系统、智能配电网或电力电子控制等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①作为微电网二次控制算法的教学案例与科研仿真平台;②为分布式能源系统的电压频率稳定控制与功率均衡分配提供先进的算法设计与性能验证方案;③支持对事件触发控制、通信优化策略在实际电力系统中的应用效果进行评估、改进与推广。; 阅读建议:建议结合提供的Simulink模型与配套代码进行动手实践,重点剖析控制器的设计逻辑、事件触发条件的设定原则以及通信机制的实现方式,通过主动修改负载参数、调整通信拓扑结构等方式,深入探究系统在不同运行条件下的动态特性与鲁棒性表现。
当前位置:首页 所有数据 企业数据 正文 600多家商业银行数据大全 2007-2024年 zh899_mary 2026-04-22 其他数据 3.74k 01、数据介绍 数据包括全国600多家银行数据,包括上市银行非上市银行基本信息,资产负债、利润、财务指标、现金流量表、流动性风险、市场风险、信用风险、存款结构等数据表。 数据名称:600多家商业银行数据大全 数据年份:2007-2024年 02、数据指标 银行代码 银行中文简称 统计截止日期 报表类型 股票代码 存款总额 公司存款 公司定期存款 公司活期存款 个人存款 个人定期存款 个人活期存款 保证金存款 公司存款占比 公司定期存款占比 公司活期存款占比 个人存款占比 个人定期存款占比 个人活期存款占比 保证金存款占比 银行代码 股票代码 统计截止日期 银行中文简称 核心一级资本 核心一级资本扣除项目 核心一级资本净额 附属资本净额 其他一级资本 一级资本净额 二级资本 其中:享受优惠政策可计入部分 二级资本扣除项目 二级资本净额 资本净额 信用风险加权资产 市场风险加权资产 操作风险加权资产 其他 风险加权资产合计 资本充足率 一级资本充足率 核心资本充足率 加权风险资产收益率 风险加权资产对总资产比率 风险加权资产对生息资产比率 风险加权资产对总贷款比率 穆迪评级-中国主权 穆迪评级-银行 穆迪评级展望 标准普尔评级-中国主权 标准普尔评级-银行 标准普尔评级展望 惠誉评级-中国主权 惠誉评级-银行 惠誉评级展望 银行代码 股票代码 统计截止日期 银行中文简称 利率风险敏感度 累计外汇头寸敞口比例 风险资本利润率 杠杆率 资产利润率 资本利润率 成本收入比例 银行代码 股票代码 统计截止日期 银行中文简称 流动性比例(本币) 流动性比例(外币) 流动性比例(
内容概要:本文系统阐述了正规表达式(正则表达式)作为词法分析核心工具的理论基础与实际应用。文章从字母表、符号串等基本概念出发,详细介绍了正规式的定义、运算规则、代数性质及其与有限自动机(NFA/DFA)的等价关系,阐明了通过Thompson构造法、子集构造法DFA最小化实现词法分析器自动生成的技术路径。同时,文中列举了标识符、关键字、运算符等编程语言元素的正规式描述,并说明了最长匹配优先级规则在歧义消解中的作用。此外,还对比了正规式与上下文无关文法的表达能力差异,指出了其在嵌套结构计数能力上的局限性,并介绍了Lex/Flex等词法分析器生成工具的应用场景。; 适合人群:计算机相关专业学生、编译原理初学者、希望深入理解词法分析机制的研发人员;具备一定的离散数学形式语言基础者更佳。; 使用场景及目标:① 学习如何使用正规表达式精确描述程序语言的词法规则;② 掌握从正规式到DFA的转换流程及其实现原理,为构建编译器前端打下基础;③ 理解词法分析器生成工具的工作机制,提升对自动化工具的理解与运用能力。; 阅读建议:建议结合编译器设计实践进行学习,尝试手动完成正规式到NFA再到DFA的转换练习,并使用Flex等工具验证结果,以加深对理论知识的理解与应用。
内容概要:本文深入解析了RF PCB为何必须控制在50Ω阻抗,并详细阐述了阻抗不匹配对5G性能的影响。文章从射频信号的传输特性出发,介绍了传输线理论、特征阻抗的形成因素(如线宽、介质厚度、参考地等),解释了50Ω作为行业标准的工程合理性。进一步讲解了阻抗不连续引发的信号反射、回波损耗、VSWR等问题,及其对发射功率、EVM、天线效率接收灵敏度的负面影响。结合车载TBOX应用场景,强调了完整参考地、避免噪声干扰、合理使用过孔与连接器的重要性,并引入Smith圆图用于匹配网络分析。最后指出RF系统各环节必须保持阻抗一致性,任何设计疏忽都可能导致整体无线性能下降。; 适合人群:从事汽车电子、射频硬件设计及相关领域的工程师,尤其是涉及5G、GNSS、WiFi等无线通信产品开发的技术人员;具备一定高频电路基础知识的研发人员;; 使用场景及目标:①理解50Ω阻抗控制的根本原因及其在5G高频下的关键作用;②掌握RF PCB设计中阻抗匹配、减少反射、优化回波损耗的设计方法;③应用于车载TBOX等复杂多天线系统的射频完整性设计与调试;④提升对射频系统整体链路(PA→走线→连接器→天线)协同设计的认知水平;; 阅读建议:此资源理论与实践结合紧密,建议读者结合实际PCB Layout案例,配合S参数测试、S11测量OTA验证进行对照学习,重点关注地平面完整性、噪声隔离与匹配网络调整,以全面提升射频系统设计能力。
内容概要:本文提出了一种事件触发驱动的微电网分布式二次协同控制策略,旨在解决孤岛微电网中电压与频率的快速恢复以及分布式电源间功率精确均衡分配的问题。该策略融合事件触发机制与分布式一致性算法,有效降低传统周期性通信带来的资源消耗,在确保控制性能的同时显著减少通信负担。研究构建了包含分布式电源、负载及通信拓扑的微电网系统模型,设计了基于事件触发条件的分布式控制器,仅在系统偏差超过设定阈值时才进行信息更新与传输,从而实现资源节约与控制精度的平衡。通过Simulink仿真实验验证了该方法在不同负载扰动网络拓扑变化下的有效性与鲁棒性,能够实现电压频率的无静差调节按需功率分配。; 适合人群:从事电力系统自动化、微电网控制、分布式能源管理及相关领域的研究生、科研人员及工程技术人员,尤其适合具备自动控制理论基础MATLAB/Simulink仿真能力的研究者。; 使用场景及目标:①应对孤岛微电网中因高频通信引发的带宽紧张与节点能耗问题;②实现电压频率稳定与功率均分的双重控制目标,提升系统运行的经济性与可靠性;③为通信资源受限环境下的微电网分布式协同控制提供理论依据与仿真验证手段。; 阅读建议:建议读者结合控制算法设计逻辑与Simulink模型结构对照学习,重点关注事件触发条件的设计、一致性协议的实现方式及仿真参数配置,可通过调整触发阈值或改变网络拓扑深入探究其对系统动态响应特性的影响。
内容概要:本文提出了一种面向综合能源系统的算力-电力-热力联合优化调度策略,旨在实现多能源耦合系统中的高效协同运行。研究通过构建涵盖算力负荷(如数据中心计算任务)、电力系统与热力系统的综合模型,利用Matlab进行仿真与优化求解,深入整合三者的能量流动关系与动态耦合特性。重点分析了算力负载的时空迁移特性及其对电力与热力供需平衡的影响机制,引入先进的优化算法实现系统经济性、能效性可再生能源消纳能力的多目标协同优化。该方法有效提升了综合能源系统的资源综合利用效率,降低了运行成本,并增强了系统灵活性与可持续性。; 适合人群:具备电力系统、能源工程、自动化或相关领域背景,熟悉Matlab编程,从事综合能源系统、智能电网、数据中心能耗管理或能源互联网研究的研发人员与高校研究生。; 使用场景及目标:①应用于数据中心与区域能源系统协同调度的实际工程场景;②服务于科研中对多能耦合系统建模、优化算法设计与验证的需求;③实现节能减排、提升系统运行经济性与对可再生能源的高比例消纳目标。; 阅读建议:建议结合提供的Matlab代码深入理解模型构建、变量定义与求解流程,重点关注算力与能源系统间的耦合建模方法,可通过调整负荷参数、引入新的约束条件或更换优化算法进行二次开发与拓展研究。
内容概要:本文针对2MW级新能源并网系统,开展虚拟同步发电机(VSG)控制系统的建模与暂态稳定性仿真分析,重点基于Simulink平台构建完整的VSG控制系统仿真模型,深入研究其在并网过程中的动态响应特性与暂态稳定性能。文中系统阐述了VSG的核心控制原理,包括虚拟惯量与虚拟阻尼的引入机制及其对系统频率支撑低电压穿越能力的提升作用,详细分析了VSG在电网扰动、短路故障等典型暂态工况下的运行表现,并通过多场景仿真对比,验证了VSG控制策略在增强新能源系统稳定性方面的有效性。研究为高比例可再生能源接入背景下的电力系统稳定控制提供了重要的仿真依据与技术参考。; 适合人群:具备电力系统分析、电力电子变换及自动控制理论基础,熟悉Simulink/MATLAB仿真环境,从事新能源并网技术、微电网控制、电力系统稳定性研究的研究生、科研人员及电力行业工程技术人员。; 使用场景及目标:① 掌握VSG控制的基本原理与Simulink建模方法;② 深入理解虚拟惯量阻尼参数对系统暂态稳定性的调控机理;③ 通过设置短路、负载突变等故障场景,仿真评估VSG系统在复杂工况下的鲁棒性与恢复能力;④ 为新能源并网项目的科研仿真、学位论文课题或实际工程控制策略设计提供可复用的模型范例与分析方法。; 阅读建议:学习者应结合电力系统暂态稳定理论,重点关注VSG控制模块的结构设计、关键参数(如转动惯量、阻尼系数)的整定原则,并建议动手复现仿真模型,通过调整电网强度、故障类型及控制参数进行对比试验,从而深刻掌握VSG提升系统稳定性的内在物理机制与工程应用要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值