Отражение Java, где параметр метода является интерфейсом - PullRequest
3 голосов
/ 24 августа 2010

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

Теперь происходит то, что они создали серию методов, которые вызываются отражением. Один из этих методов принимает Map в качестве одного из аргументов. Во время выполнения эта Карта реализуется с помощью Hashtable.

Вот проблема - я получаю NoSuchMethodException, потому что он ищет метод с Hashtable в качестве аргумента, хотя Hashtable реализует интерфейс Map. Что меня смущает, так это то, что если я не использую рефлексию (в данном случае значительное изменение дизайна) и передаю Hashtable, то он вызывает метод с параметром Map - так почему же он не работает так же, когда я использую отражение

Учитывая, что мне в значительной степени приходится придерживаться рефлексии, есть ли способ получить метод с аргументом Map, который будет вызываться при передаче ему класса, реализующего этот интерфейс?

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

Ответы [ 2 ]

4 голосов
/ 24 августа 2010

Если вы используете getMethod(String name, Class[] parameterTypes) из java.lang.Class, вам необходимо указать типы параметров, выраженные в сигнатуре метода интерфейса (статический тип), а не тип объекта во время выполнения (динамический тип).

Итак, для methodXyz(Map map) вместо:

Method m = cl.getMethod("methodXyz", new Class[]{argument.getClass()});

сделайте следующее:

Method m = cl.getMethod("methodXyz", new Class[]{Map.class});
1 голос
/ 24 августа 2010

У меня была похожая проблема. Я вижу 2 решения:

решение 1: Вы можете разработать более сложный метод поиска.

Пример алгоритма, который вы можете использовать:

Вы ищете с типом параметра. Если поиск завершается неудачно (Исключение), но один из параметров имеет супертип (или реализует интерфейс), вы выполняете поиск по тому же имени метода, но с этим суперклассом (или интерфейсом). Вы сгенерируете исключение, только если после этого алгоритма поиска метод не найден.

Примечание: если ваши методы имеют несколько параметров, обязательно проверяйте каждую возможную комбинацию супертипов / интерфейсов. Это может привести к довольно сложному алгоритму поиска ...

решение 2: другой способ, гораздо более простой, состоит в уточнении типов отдельно от параметров. Этот метод может быть более подробным, если вы хотите использовать нулевые параметры.

Итак, " invokeMethod (String methodName, Object [] paramters) " становится " invokeMethod (String methodName, Class [] methodParamTypes , Object [] параметры) ».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...