摘要:公司使用来作为通讯格式,一个同事这样的写法文件格式使用的时候这时候拿到的是一个要是改成这样这时候拿到的是一个为什么会出现这种情况呢读了源码才知道是这样处理的这里发现只要才会进行包装,要不调用的是那么是什么时候变成不为呢继续看代码发现只要是调
公司使用protobuf来作为通讯格式,一个同事这样的写法
proto文件格式:
message PlayerFightQueue { optional int32 fightQueueId = 1; repeated CurArmy curArmy = 2; }
使用的时候:
PlayerFightQueue.Builder fightQueue= getPlayerFightQueue(); Listarmies = fightQueue.getCurArmyList(); 这时候armies拿到的是一个java.util.Collections.unmodifiableList
要是改成这样:
PlayerFightQueue.Builder fightQueue= getPlayerFightQueue(); fightQueue.getCurArmyBuilderList(); Listarmies = fightQueue.getCurArmyList(); 这时候armies拿到的是一个RepeatedFieldBuilder.list
为什么会出现这种情况呢?
读了源码才知道protobuf是这样处理的:
public java.util.ListgetCurArmyList() { if (curArmyBuilder_ == null) { return java.util.Collections.unmodifiableList(curArmy_); } else { return curArmyBuilder_.getMessageList(); } }
这里发现只要curArmyBuilder_ == null才会进行包装,要不调用的是curArmyBuilder_.getMessageList()
那么curArmyBuilder_ 是什么时候变成不为null呢?
继续看代码:
public java.util.ListgetCurArmyBuilderList() { return getCurArmyFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< com.wl.protocol.rpc.msg.CurArmyMsg.CurArmy, com.wl.protocol.rpc.msg.CurArmyMsg.CurArmy.Builder, com.wl.protocol.rpc.msg.CurArmyMsg.CurArmyOrBuilder> getCurArmyFieldBuilder() { if (curArmyBuilder_ == null) { curArmyBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< com.wl.protocol.rpc.msg.CurArmyMsg.CurArmy, com.wl.protocol.rpc.msg.CurArmyMsg.CurArmy.Builder, com.wl.protocol.rpc.msg.CurArmyMsg.CurArmyOrBuilder>( curArmy_, ((bitField0_ & 0x00000080) == 0x00000080), getParentForChildren(), isClean()); curArmy_ = null; } return curArmyBuilder_; }
发现只要是调用了builder方法会改变curArmyBuilder_ 而curArmy_就会被变成null
遇到这种情况还是不要偷懒,老老实实的深复制吧,也许就会出现埋点很深的坑
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/66349.html
摘要:优点在谷歌内部长期使用产品成熟度高跨语言支持多种语言包括和编码后的消息更小更加有利于存储和传输编解码的性能非常高支持不同协议版本的前向兼容支持定义可选和必选字段的入门是一个灵活高效结构化的数据序列化框架相比与等传统的序列化工具它更小更快更简 Google Protobuf 优点: 在谷歌内部长期使用, 产品成熟度高. 跨语言、支持多种语言, 包括 C++、Java 和 Python....
摘要:结构作为服务端作为序列化数据的协议前端通讯演示地址服务端实现启动类长连接示例主线程组从线程组请求的解码和编码把多个消息转换为一个单一的或是,原因是解码器会在每个消息中生成多个消息对象主要用于处理大数据流,比如一个大小的文件如果你直接传输肯定 结构 netty 作为服务端 protobuf 作为序列化数据的协议 websocket 前端通讯 演示 GitHub 地址 showImg(...
阅读 2025·2023-04-25 17:48
阅读 3561·2021-09-22 15:37
阅读 2843·2021-09-22 15:36
阅读 5740·2021-09-22 15:06
阅读 1621·2019-08-30 15:53
阅读 1397·2019-08-30 15:52
阅读 682·2019-08-30 13:48
阅读 1098·2019-08-30 12:44