为什么Avro生成的代码是接口而非类,无法调用newBuilder()方法?
Avro生成接口而非类的原因及解决方案
核心原因
你的AVDL定义中协议名和内部记录名重名,触发了Avro IDL的默认编译规则:
- Avro会为每个
protocol生成一个同名接口,用于承载该协议下的所有RPC方法、内部类型定义 - 你定义的
protocol SampleRecord和内部record SampleRecord完全重名,编译后实际的记录类会生成为协议接口的内部类,全限定名为com.example.SampleRecord.SampleRecord - 你代码中直接导入的是外层的协议接口
com.example.SampleRecord,自然找不到newBuilder()方法
解决方案
方案1:修改协议名(推荐)
调整AVDL的协议名,避免和内部记录重名,修改后的AVDL示例:
@namespace("com.example") protocol SampleProtocol { record SampleRecord { string id; string description; string value; } }
修改后编译会直接生成独立的com.example.SampleRecord记录类,原有调用逻辑适配类型后即可正常运行。
方案2:引用内部记录类
如果不修改AVDL,直接使用全限定名调用内部记录类即可:
return (data -> { return Flux.fromIterable(data) .map(sampleRecord -> com.example.SampleRecord.SampleRecord.newBuilder() .setId("1") .setDescription("desc") .setValue("42") .build()) .collectList(); });
额外注意事项
你原代码中存在类型不匹配问题:AVDL定义的id、value均为string类型,你调用setId(1)、setValue(42)传入的是整型,即使类加载问题解决后也会触发类型报错,需要调整为字符串类型传参。
内容的提问来源于stack exchange,提问作者Johnathan J.
相关产品推荐
相关产品推荐

