2016-08-12 5 views
3

Обычно вы создаете экземпляр класса Protobuf вроде этого:Как создать экземпляры protobuf с использованием java-отражения?

Bar.Builder bld = Bar.newBuilder(); 
bld.setXYZ(... 

У меня есть UseCase, который использует отражение Java для создания экземпляра класса Protobuf:

Class clsBar = Class.forName("com.xyz.Foo$Bar"); 
Object instance = clsBar.newInstance(); // error here! 
Method mth = clsBar.getMethod(...); 

Приведенный выше код отлично работает с обычными классами Java , Но для сгенерированного класса protobuf "com.xyz.Foo$Bar", он дает мне NoSuchMethodException, так как там нет общедоступного конструктора по умолчанию.

Любые предложения о том, как использовать Java-рефлексию для создания экземпляров protobuf? Вопрос в том, кто действительно хорошо разбирается в протобуфе. Спасибо!

+0

Что делать, если вы вызвали clsBar.getConstructors() и вызвали метод .newInstance() на одном из возвращаемых объектов Constructor? – Duston

+0

Какая информация у вас есть? Только желаемый класс или больше? Если вы хотите создать экземпляр Protobuf из массива байтов или аналогичного, вы можете использовать метод 'parseFrom'. – dpr

+0

@Duston Все конструкторы являются частными, поскольку реализация protobuf идет. Для dpr у меня есть только полные квалифицированные имена классов, которые генерируют классы protobuf. –

ответ

3

Я думаю, вы должны пойти на полный путь: через класс Builder:

//get Bar class 
Class barClass = Class.forName("com.xyz.Foo$Bar"); 

//instantiate Builder through newBuilder method 
Method newBuilderMethod = barClass.getMethod("newBuilder"); 
Bar.Builder builder = (Bar.Builder) newBuilderMethod.invoke(null); 

// ... set properties -- can be through reflection if necessary 

//build: 
Bar bar = builder.build(); 

Хотя я точно не вижу, как отражение любого использования в данном случае, это, вероятно, потребует более глубокого понимания точная проблема, которую вы пытаетесь решить.

+1

Ваш ответ в правильном направлении, но с незначительной ошибкой: метод «newBuilder» относится к классу «Bar», а не «Bar $ Builder». Благодаря! –

+0

@NathanW исправил это - похоже, я не уделял достаточного внимания ... – ppeterka