protobuf extensions(extend)的消息定义及Java使用方法

在定义protobuf消息时,有时候需要用到extensions来对原有的消息类型进行扩展,有利于消息定义的重复使用。

1、下面写一个最简单的例子,定义一个message BaseData,并对其进行扩展:

Example.proto:

// 定义一个message BaseData,100~199之间的tag可供扩展
message BaseData {
	required int32 code = 1;
	extensions 100 to 199;
}

// 扩展BaseData,加上一个extend_data,tag为100
extend BaseData {
	required string extend_data = 100;
}

运行protoc.exe --java_out=. Example.proto生成Example.java文件。

Java代码:

public static void main(String[] args) {

	Example.BaseData.Builder baseBuilder = Example.BaseData.newBuilder();
	baseBuilder.setCode(123);
	baseBuilder.setExtension(Example.extendData, "xxg");
	Example.BaseData baseData = baseBuilder.build();

	System.out.println(baseData.getCode());
	System.out.println(baseData.getExtension(Example.extendData));
}

这里需要调用setExtension方法来设置扩展的extendData。setExtension有两个参数,第一个定义扩展的是哪一个字段,Example.extendData即表示Example类中的extendData,第二个就是设置扩展字段的值。

2、另外还有一种常用的扩展定义方式:

Example.proto:

// 定义一个message BaseData,100~199之间的tag可供扩展
message BaseData {
	required int32 code = 1;
	extensions 100 to 199;
}

// 定义一个message Data
message Data {
	required string msg = 1;

	// 扩展BaseData,加上一个Data类型的字段,tag为100
	extend BaseData {
		required Data extend_data = 100;
	}
}

这种方式看起来有点奇怪,实际上可以理解成这样:

// 定义一个message BaseData,100~199之间的tag可供扩展
message BaseData {
	required int32 code = 1;
	extensions 100 to 199;
}

// 定义一个message Data
message Data {
	required string msg = 1;
}

// 扩展BaseData,加上一个Data类型的字段,tag为100
extend BaseData {
	required Data extend_data = 100;
}

Java代码:

public static void main(String[] args) {

	// 先构造一个message Data类型对象
	Example.Data.Builder dataBuilder = Example.Data.newBuilder();
	dataBuilder.setMsg("xxg");
	Example.Data data = dataBuilder.build();

	// 再构造message BaseData对象,将Data对象通过setExtension设置到BaseData中
	Example.BaseData.Builder baseBuilder = Example.BaseData.newBuilder();
	baseBuilder.setCode(123);
	baseBuilder.setExtension(Example.Data.extendData, data);
	Example.BaseData baseData = baseBuilder.build();

	System.out.println(baseData.getCode());
	System.out.println(baseData.getExtension(Example.Data.extendData).getMsg());
}

注意上面的Java代码用的是第一种proto消息定义方式,如果用的是下面第二种消息定义的方式,setExtension的参数Example.Data.extendData就应该改成Example.extendData,注意嵌套结构。

作者:叉叉哥   转载请注明出处:http://blog.csdn.net/xiao__gui/article/details/37874081

protobuf extensions(extend)的消息定义及Java使用方法

时间: 2024-10-13 17:21:21

protobuf extensions(extend)的消息定义及Java使用方法的相关文章

Android消息机制1-Handler(Java层)(转)

转自:http://gityuan.com/2015/12/26/handler-message-framework/ 相关源码 framework/base/core/java/andorid/os/Handler.java framework/base/core/java/andorid/os/Looper.java framework/base/core/java/andorid/os/Message.java framework/base/core/java/andorid/os/Mes

js 定义像java一样的map方便取值

js 定义像java一样的map方便取值. 百度有位大神说"js对象本身就是一种Map结构",这真是一段让人欢天喜地的代码. <script> //定义一个全局map var map = {}; var key0 = '0'; var key1 = '1'; map[key0] = '0-真实报文'; map[key1] = '1-虚拟报文'; //row 获取这行的值 ,index 获取索引值 function testJsMap(key){ //如果遍历map for(

protobuf 中的嵌套消息的使用

protobuf的简单的使用,不过还留下了一个问题,那就是之前主要介绍的都是对简单数据的赋值,简单数据直接采用set_xx()即可,但是如果不是简单变量而是自定义的复合类型变量,就没有简单的set函数调用了,下面看一个简单的例子. 在网络游戏中,游戏玩家之间的同步是一个最基本的功能,而同步是通过对坐标的广播进行的,因此我们假设一个简单的模型,当一个玩家的位置发生变化时,将玩家的新位置发给地图内所有玩家,根据这个情况写出以下proto文件.   message PlayerPos{ require

java 虚方法。 后面new 那个类, 就调用哪个类的方法 ,而非定义类的方案。 关于父子 类的 呵呵

java   虚方法.     后面new  那个类, 就调用哪个类的方法 ,而非定义类的方案.  关于父子 类的   呵呵 在多态的情况下,声明为父类类型的引用变量只能调用父类中的方法,但如果此变量实际引用的是子类对象,而子类对象中覆盖了父类的方法,这时父类对象调用的是子类中的方法,这种机制就成为虚方法调用.所以,同样的两个引用变量调用相同的方法结果可能不同.

java中方法的定义

java中方法的定义: [修饰符]   [修饰符]   [返回值类型] 方法名字 [形参列表] //带[]的可以省略,返回值类型不能省略. 就拿main方法来说,public         static       void       main (String[] args){ 方法体: return 返回值://返回值要与返回值类型相匹配.没有返回值的话,返回值类型用void; } 方法的定义:为了完成某项功能,封装的一系列代码的集合: 方法的调用:同一个类中可以直接用方法名():调用:但

JNI/NDK开发指南(二)——JVM查找java native方法的规则

通过第一篇文章,大家明白了调用native方法之前,首先要调用System.loadLibrary接口加载一个实现了native方法的动态库才能正常访问,否则就会抛出java.lang.UnsatisfiedLinkError异常,找不到XX方法的提示.现在我们想想,在Java中调用某个native方法时,JVM是通过什么方式,能正确的找到动态库中C/C++实现的那个native函数呢? JVM查找native方法有两种方式: 1> 按照JNI规范的命名规则 2> 调用JNI提供的Regist

java基本方法

Java 方法 在前面几个章节中我们经常使用到 System.out.println(),那么它是什么呢? println() 是一个方法. System 是系统类. out 是标准输出对象. 这句话的用法是调用系统类 System 中的标准输出对象 out 中的方法 println(). 那么什么是方法呢? Java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 方法的优点 1. 使程序变得更简短而清晰

RMI - Java远程方法调用

一.入门篇 Java RMI指的是远程方法调用(Remote Method Invocation). 它是一种机制, 能够让不同操作系统之间程序实现方法调用. 比如: 一台电脑上的Java程序可以通过RMI调用另一台电脑上的方法(EJB底层就是使用RMI). 二.RMI和webservice RMI是在TCP协议上传递可序列化的Java对象, 只能用在Java虚拟机上, 客户端和服务端必须都是Java. webservice是在http协议上传递xml文件, 它与语言和平台无关, 可以在异构系统

几种任务调度的 Java 实现方法与比较

几种任务调度的 Java 实现方法与比较 综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,并对其优缺点进行比较,目的在于给需要开发任务调度的程序员提供有价值的参考. 前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Qua