Поведение Java Class.getMethods () в переопределенных методах - PullRequest
6 голосов
/ 01 июня 2011

При написании простого сериализатора JSON, использующего отражение в Java, я был застигнут врасплох поведением Class.getMethods (). Похоже, что Java Class.getMethods () возвращает как переопределенные, так и переопределенные методы, если возвращаемый тип переопределенного метода расширяет тип возвращаемого значения переопределенного метода.
Так, например, учитывая интерфейсы:

static interface A {
  A x();
  A y();
}
static interface B extends A {
  B x();
  A y();
}

A.class.getMethods() возвращает и массив двух методов, как и ожидалось однако B.class.getMethods() возвращает массив из 3 методов (что для меня было немного противоречивым). Из 3 1 соответствует y(), как и ожидалось, но остальные два соответствуют исходному x() с типом возврата A и переопределяющей версии x() с типом возврата B соответственно. Это показалось мне немного странным, но иметь в исходном тексте x(), поскольку он нигде не доступен. В любом случае, мой вопрос таков:
Существует ли простой способ получить список только самых специализированных версий методов класса, не прибегая к ручной проверке переопределенных методов и их фильтрации?

Ответы [ 3 ]

7 голосов
/ 01 июня 2011

Насколько я понимаю, если вы отфильтруете методы, для которых isBridge() возвращает true, нежелательный метод должен исчезнуть.

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

edit Интересно, что, хотя это работает для классов, оно не работает для интерфейсов.Все три метода B помечены как немостовые и не синтетические.Однако, если я создаю неабстрактный класс C, реализующий B, его A x() помечается как промежуточный и синтетический.

4 голосов
/ 01 июня 2011

То, что у вас есть, называется "ковариантным возвратом".

Как указывает aix, похоже, вам приходится иметь дело с методами моста.Прочитайте это: http://stas -blogspot.blogspot.com / 2010/03 / java-bridge-Methods-объясненный.html (игнорировать текст о дженериках) и это: Проблема в GetDeclaredMethods (Java)

0 голосов
/ 01 июня 2011

Один из способов заключается в том, чтобы сказать: B.class.getDeclaredMethods(), однако, это вернет только методы, отклоненные в B. Итак, если у вас есть C, расширение B реализует A, C.class.getDeclaredMethods() не вернет методы, которые вы не переопределили.

, если вы хотите выполнить итерацию, хороший способ сделать это -

for (Method m: B.class.getMethods()) {
  if (m.getDeclaringClass() == Object.class || m.declaringClass() == A.class) 
    continue;
  // otherwise do some stuff
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...