我正在迭代GPB消息的字段,并且必须找出消息中已设置的字段列表
public void printFields(Person person){
Builder builder = person.toBuilder();
Descriptor descriptor = Person.getDescriptor();
List<FieldDescriptor> fields = descriptor.getFields();
for(FieldDescriptor fd : fields){
Object value = builder.get(fd); //this gives the value
// how to check if this field is set or not
}
}
将value
检查为null并没有帮助,因为消息中也可以有原始类型。
我已经阅读了有关消息类的hasXXX()方法,它告诉XXX是否具有默认值或显式值,但是如何使用builder / descriptor / fieldDescriptor调用它们。
答案 0 :(得分:0)
已经晚了,但对其他人可能有用..
以下代码将打印修改后的属性名称及其值。你可以改变它来识别proto中的填充属性
Map<Descriptors.FieldDescriptor, Object> modifiedFields = proto.getAllFields();
for(Descriptors.FieldDescriptor fieldDescriptor : modifiedFields.keySet())
{
int protNum = fieldDescriptor.toProto().getNumber();
Descriptors.FieldDescriptor.Type fieldType = fieldDescriptor.getType();
Object value = modifiedFields.get(fieldDescriptor);
System.out.println(fieldDescriptor.getFullName());
System.out.println(value);
}
答案 1 :(得分:0)
如果您使用的是Java 8,则可以使用流式API查找已定义的字段:
List<Descriptors.FieldDescriptor> definedPersonFields = Person.getDescriptor()
.getFields()
.stream()
.filter(Person::hasField)
.collect(Collectors.toList())
答案 2 :(得分:-1)
为什么需要使用descriptor / fieldDescriptor?如果您定义“option optimize_for = LITE_RUNTIME”,它们甚至不可用。 无论如何,你可以在Person.Builder或者只有Person上做到这一点,例如:
Builder builder = person.toBuilder();
if (builder.hasXXX()){
XXX xxx = builder.getXXX();
}