资讯专栏INFORMATION COLUMN

使用java google protobuf遇到一个的小坑

tinysun1234 / 3002人阅读

摘要:公司使用来作为通讯格式,一个同事这样的写法文件格式使用的时候这时候拿到的是一个要是改成这样这时候拿到的是一个为什么会出现这种情况呢读了源码才知道是这样处理的这里发现只要才会进行包装,要不调用的是那么是什么时候变成不为呢继续看代码发现只要是调

公司使用protobuf来作为通讯格式,一个同事这样的写法
proto文件格式:

message PlayerFightQueue {
    optional  int32      fightQueueId            = 1;
    repeated  CurArmy     curArmy                = 2;
}

使用的时候:

PlayerFightQueue.Builder fightQueue= getPlayerFightQueue();
List armies = fightQueue.getCurArmyList();



这时候armies拿到的是一个java.util.Collections.unmodifiableList


要是改成这样:

PlayerFightQueue.Builder fightQueue= getPlayerFightQueue();
fightQueue.getCurArmyBuilderList();
List armies = fightQueue.getCurArmyList();

这时候armies拿到的是一个RepeatedFieldBuilder.list


为什么会出现这种情况呢?
读了源码才知道protobuf是这样处理的:

  public java.util.List getCurArmyList() {
    if (curArmyBuilder_ == null) {
      return java.util.Collections.unmodifiableList(curArmy_);
    } else {
      return curArmyBuilder_.getMessageList();
    }
  }

这里发现只要curArmyBuilder_ == null才会进行包装,要不调用的是curArmyBuilder_.getMessageList()
那么curArmyBuilder_ 是什么时候变成不为null呢?
继续看代码:

 public java.util.List 
       getCurArmyBuilderList() {
    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

相关文章

  • 源码MySQL5.7.20 安装

    摘要:关系型数据库管理系统是一个关系型数据库管理系统,由瑞典公司开发,目前属于旗下产品。是最流行的关系型数据库管理系统之一,在应用方面,是最好的,关系数据库管理系统应用软件。启动进程设置开机启动安装解压创建源。 mySQL (关系型数据库管理系统) MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发, 目前属于 Oracle 旗下产品。MySQL 是最流行...

    Chiclaim 评论0 收藏0
  • Google Protocol Buffers + Android micro/nano runti

    摘要:最近做的项目涉及到,所以就顺便整理上来分享一下吧。也就是说,把定义好的数据转换为经过精心安排的二进制形式,或者反过来。相较于或更省流量。官方版的自带了和的支持。这条命令会将代码检出到目录下。在项目中使用配置运行时首先,我讨厌,我讨厌。 最近做的项目涉及到 Protobuf,所以就顺便整理上来分享一下吧。 Protocol Buffers (aka. protobuf) 是啥? 一套...

    willin 评论0 收藏0
  • 腾讯优测-优社区干货精选 | android开发在路上:少去踩坑,多走捷径(上)

    摘要:文腾讯公司陈江峰优测小优有话说开发的坑自然是不少,不想掉坑快来优测优社区最近一朋友提了几个问题让我帮忙写个小分享,我觉得对新人还是挺有帮助的。 文/腾讯公司 陈江峰优测小优有话说: android开发的坑自然是不少,不想掉坑快来优测优社区~ 最近一朋友提了几个Android问题让我帮忙写个小分享,我觉得对新人还是挺有帮助的。于是在原基础上针对我们的业务,对回答做了一些修改和补充。 1....

    Charlie_Jade 评论0 收藏0
  • Google Protobuf 编解码

    摘要:优点在谷歌内部长期使用产品成熟度高跨语言支持多种语言包括和编码后的消息更小更加有利于存储和传输编解码的性能非常高支持不同协议版本的前向兼容支持定义可选和必选字段的入门是一个灵活高效结构化的数据序列化框架相比与等传统的序列化工具它更小更快更简 Google Protobuf 优点: 在谷歌内部长期使用, 产品成熟度高. 跨语言、支持多种语言, 包括 C++、Java 和 Python....

    Eric 评论0 收藏0
  • netty 基于 protobuf 协议 实现 websocket 版本简易客服系统

    摘要:结构作为服务端作为序列化数据的协议前端通讯演示地址服务端实现启动类长连接示例主线程组从线程组请求的解码和编码把多个消息转换为一个单一的或是,原因是解码器会在每个消息中生成多个消息对象主要用于处理大数据流,比如一个大小的文件如果你直接传输肯定 结构 netty 作为服务端 protobuf 作为序列化数据的协议 websocket 前端通讯 演示 GitHub 地址 showImg(...

    wua_wua2012 评论0 收藏0

发表评论

0条评论

tinysun1234

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<