关于protostuff 序列化 list 不一致问题

窦立阳 窦立阳 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
对对象A序列化,A中含有B对象,B对象中包含一个List,初始化后含有一项rpc-list,
序列化后生成byte[],我定义为test
当对test进行反序列话后,却出现了两个rpc-list。
控制台输出的:
print A-B-List before serialize
list[0]=rpc-list
print A-B-List after serialize
list[0]=rpc-list
list[1]=rpc-list
/******************************/
class A

public class A {
Object C;

public Object getC() {
return C;
}

public void setC(Object c) {
C = c;
}

public static void main(String[] args) {
B b = new B();
A a=new A();
a.setC(b);

B bb=(B)a.getC();
System.out.println("print A-B-List before serialize");
for (int i = 0; i < bb.getList().size(); i++) {
System.out.println("list["+i+"]="+bb.getList().get(i));
}
byte[] test=SerializationUtil.serialize(a);
A newA=SerializationUtil.deserialize(test, A.class);
bb=(B)newA.getC();
System.out.println("print A-B-List after serialize");
for (int i = 0; i < bb.getList().size(); i++) {
System.out.println("list["+i+"]="+bb.getList().get(i));
}

System.out.println();
}
}


/******************************/

public class B {
private int num;
private String str;
private List<String> list;
public B() {
num = 3;
str = "rpc";

list = new ArrayList<String>();
list.add("rpc-list");
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}


}

/******************************/
序列化的类

public class SerializationUtil {

private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();

private static Objenesis objenesis = new ObjenesisStd(true);

private SerializationUtil() {
}

@SuppressWarnings("unchecked")
private static <T> Schema<T> getSchema(Class<T> cls) {
Schema<T> schema = (Schema<T>) cachedSchema.get(cls);
if (schema == null) {
schema = RuntimeSchema.createFrom(cls);
if (schema != null) {
cachedSchema.put(cls, schema);
}
}
return schema;
}


/**
* 序列化(对象 -> 字节数组)
*/
@SuppressWarnings("unchecked")
public static <T> byte[] serialize(T obj) {
Class<T> cls = (Class<T>) obj.getClass();
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
try {
Schema<T> schema = getSchema(cls);
return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
} finally {
buffer.clear();
}
}

/**
* 反序列化(字节数组 -> 对象)
*/
public static <T> T deserialize(byte[] data, Class<T> cls) {
try {
T message = (T) objenesis.newInstance(cls);
Schema<T> schema = getSchema(cls);
ProtostuffIOUtil.mergeFrom(data, message, schema);
return message;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}

/******************************/
...全文

相关推荐

spring data redis 封装使用

基于SpringBoot搭建 Redis操作 包括String、Hash、List、Set、ZSet 使用protostuff序列化和反序列化 注释齐全欢迎大家下载使用

SoulBGM

Redis缓存Java List对象:序列化方案、数据结构选择与性能优化实战

序列化是将对象转换为可存储或传输格式的核心技术,其原理在于将内存中的数据结构编码为字节流或字符串。在分布式缓存场景中,高效的序列化方案能显著提升系统性能并降低资源消耗。JSON序列化因其良好的可读性、跨语言兼容性及适中的性能,成为Java对象缓存的主流选择,尤其适用于微服务架构下的数据交换。针对List<实体>这类集合对象的缓存,开发者需根据数据规模与访问模式,在Redis的String、List、Hash等数据结构间做出权衡。例如,String类型适合整体读写的小列表,而Hash结构则便于实现基于ID的单

weixin_33704591

2026年电动汽车高压继电器行业分析:预计到2032年收入规模将接近 15082.78 百万美元.pdf

2026年电动汽车高压继电器行业分析:预计到2032年收入规模将接近 15082.78 百万美元.pdf

qyresearch报告

【Shell编程基础】变量定义与引号规则详解:交互式脚本开发核心技术及实战应用

内容概要:本文系统介绍了Shell编程中变量与交互式输入的核心知识,涵盖变量的定义、赋值、引用及删除,深入讲解了单引号、双引号、反引号和无引号的差异与使用场景。文章还阐述了位置参数和其他特殊变量(如$#、$@、$?等)的功能,介绍通过命令行传递参数及使用getopts处理选项的方法。重点说明了read命令的各种用法,包括提示信息、超时限制、隐藏输入和多变量读取,并区分了普通变量与环境变量的作用域。此外,提供了算术运算与字符串操作技巧,并通过一个完整的个人信息收集脚本实例内容概要综合应用所学内容:本文系统。; 适合讲解了Shell编程人群:具备基本中变量与交互Linux操作系统使用经验,式输入的核心知识正在学习Shell脚,涵盖变量的本编程的初级定义、赋值、引用开发者或系统管理员,、作用域及尤其适合有一定编程基础删除,深入剖析、希望提升自动化脚本编写能力的技术单引号、双引号、人员。; 使用反引号与无场景及目标:引号的区别及其①掌握Shell中变量管理的最佳实践,应用场景。文章还介绍了Shell内置的特殊变量避免因引号或作用域问题导致的常见(如位置参数、错误;②学会$#、$@编写支持命令行选项、$?等与交互式输入的健壮脚本;)、参数传递机制(包括getopts③理解特殊变量和参数处理命令处理选项)、read命令实现交互式输入机制,提升脚本的灵活性与实用性;(支持提示、④通过实战案例超时、隐藏输入等功能),并掌握输入验证、区分了普通变量与流程控制与信息环境变量的作用域差异格式化输出。。此外,文中; 阅读建议包含了算术运算:建议结合实际与字符串操作方法,并通过一个完整的终端环境边学“个人信息收集脚边练,重点关注本”实战示引号使用规则例,综合运用所学知识点,帮助、变量作用域差异读者掌握实际开发及read与getopts的实际技能。; 适合人群:具备Linux应用场景,务必动手基础操作能力,运行示例代码正在学习Shell脚并尝试修改调试,以加深理解并本编程的初学者或形成良好的脚本编写有一定实践经验的技术人员习惯。。; 使用场景及目标:① 编写自动化运维脚本时正确使用变量和引号避免错误;② 实现用户交互式输入与参数解析功能;③ 理解环境变量与局部变量的区别以优化脚本结构;④ 掌握字符串处理与基本运算提升脚本灵活性; 阅读建议:建议边阅读边在实验环境中动手实践各示例代码,重点理解引号规则、变量作用域和getopts参数处理机制,结合实战脚本进行调试与扩展练习,加深对Shell编程逻辑的理解。

云计算练习生

政府科技管理者在推动科技成果转化时,如何精准匹配科技资源与产业需求?.docx

科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN
评论 8
收藏 已收藏
分享
返回顶部
窦立阳
Java 51,407 成员 86,128 内容