2011-02-04 4 views
2

Я разрабатываю приложение, которое использует интерфейс Java как больше, чем интерфейс Java, то есть во время выполнения пользователь должен иметь возможность перечислять доступные методы в классе интерфейса, что может быть что угодно:Альтернативы преобразования Java-интерфейса

private Class<? extends BaseInterface> interfaceClass. 

Во время выполнения, я хотел бы ENUM доступные методы, а затем на основе того, что выбирает пользователь, вызвать какой-либо метод.

Мой вопрос: Является ли архитектура Java «Interface» каким-либо методом для просмотра и вызова методов без использования Reflection API?

Я хотел было что-то вроде этого (Может быть, есть):

private Interface<? extends BaseInterface> interfaceAPI; 

public void someMethod(){ 
interfaceAPI.listMethods(); 
interfaceAPI.getAnnotations(); 
} 

Может быть, есть какой-то способ использовать тип Generics добиться того, чего я хочу?

Спасибо,

Федр

+0

Есть и другие способы, но они гораздо хуже, ИМХО. Вы не сказали, почему вы не хотите использовать отражение. Возможно, ваши проблемы могут быть решены. –

+0

вы можете генерировать код «на лету» (и загружать его через какой-то пользовательский загрузчик классов) ... но это то, что на самом деле делает отражение. – bestsss

ответ

5

Это именно то, для чего был создан Reflection.

1

Мой вопрос: обеспечивает ли «Интерфейс» архитектура Java любой способ для меня, чтобы подглядывать и вызывать методы без использования Reflection API?

а) Нет, отражение это единственный способ сделать это

б) не делают этого вообще. Если вы хотите динамический язык, используйте Groovy. Синтаксис (может быть) почти идентичен синтаксису java, но он имеет большую часть этой функциональности, встроенной уже. (Многие другие языки также будут работать, но Groovy ближе всего к Java при сравнении синтаксиса)

+0

что не так w/javascript? он даже доступен в самой Java? – bestsss

+0

@bestsss ничего не случилось с JS, это отличный язык, и я никогда не говорил иначе. Но когда вы сделаете рекомендацию, вы должны начать где-то –

+0

Я никогда не предполагал, что вы сказали что-нибудь о Javascript, просто интересно, как это не первый выбор. – bestsss

1

Отражение - единственный способ перечислить методы произвольного объекта. Ну, разбор байт-кода также работает, но это утомительно.

+0

Это ложное утверждение. Вы можете в значительной степени генерировать код на лету, Proxy и Reflection делает это за кулисами. Это можно сделать вручную так же хорошо. – bestsss

+0

@bestsss Когда вам задан экземпляр «Object», как вы перечислите его методы «вручную»? – Bozho

+0

@Bozho, вы получаете свой класс (Object.getClass()), чтобы найти ресурс класса '(ClassLoader.getResource (className.replace ('.', '\') +". Class ")', загружать ресурс, анализировать Константный пул, и все сделано ... Ну, есть библиотеки, которые могут сделать это (например, bcel), но это процесс. – bestsss

0

К сожалению, похоже, что отражение - единственный путь. К несчастью, потому что отражение не только медленнее, но программирование и поддержание - это хлопот. Поэтому я предлагаю вам использовать библиотеку apache bean util. (в частности, methodutils.)

1

Посмотрите на Apache Commons BeanUtils. Это отличная библиотека для программного обнаружения методов и свойств объекта легко (т. Е. Без написания низкоуровневого кода отражения). Я использовал его в нескольких проектах. Он также предоставляет более простой API для доступа к этим членам объекта после их обнаружения. PropertyUtils и MethodUtils - хорошие места для начала.

0

Хотя здесь нет никакого способа отразить отражение, можно сделать относительно безболезненным, если вы используете аннотации, чтобы отметить ваши вызываемые методы. Примером этого подхода является набор аннотаций javax.jws для веб-сервисов. Идеи, используемые там, могут быть действительно полезными, вы можете определить отображаемое имя для каждого из ваших методов/параметров, например.

0

Reflection с аннотациями работает Nicely

for (Method m : interfaceClass.getMethods()) { 
     if (m.isAnnotationPresent(UIf.class)) { 
      UIf x = m.getAnnotation(UIf.class); 
      addDefinedCommand(new CommandDef(
        interfaceClass, 
        u, 
        x.name().isEmpty() ? m.getName() : x.name(), 
        x.description()) 
      ); 
     } 
} 
Смежные вопросы