Различия между BeanInfo:methodDescriptors и классом: Объявленные методы: несколько методов с одинаковым именем и маскировка метода
При попытке получить аннотации JPA во время выполнения для некоторых свойств я столкнулся с этой проблемой. Я не могу объяснить почему.
PS: после сеанса отладки в Spring я нашел объяснение этой проблемы: мостовые методы, которые вводятся компилятором во время компиляции. Пожалуйста, смотрите мой собственный ответ на этот вопрос..
Вот пример исходного кода, повторяющего проблему (упрощенная версия реального кода).
импорт java.beans.BeanInfo; import java.beans.IntrospectionException; импорт java.beans.Introspector; import java.beans.MethodDescriptor; импорт java.io.Serializable; import java.lang.reflect.Method;
открытый класс MethodMasking {
public interface HasId<ID extends Serializable> {
void setId(ID id);
ID getId();
}
public interface Storeable extends HasId<Long> {}
class Item implements Storeable {Long id; String code;
Item(Long id, String code) { this.id = id; this.code = code; }
public Long getId() { return id; }
public void setId(Long id) {this.id = id;}
}
public static void main(String[] args) throws IntrospectionException {
final BeanInfo beanInfo = Introspector.getBeanInfo(Item.class);
java.lang.System.out.println("BeanInfo:methodDescriptors:");
final MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
for (MethodDescriptor methodDescriptor : methodDescriptors) {
java.lang.System.out.println("\t"+methodDescriptor.getMethod().getName());
}
java.lang.System.out.println("class:declaredMethods:");
final Method[] declaredMethods = Item.class.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
java.lang.System.out.println("\t"+declaredMethod.getName());
}
}
} Вывод программы:
BeanInfo:methodDescriptors:
hashCode
wait
getId
notifyAll
equals
wait
wait
toString
setId
notify
setId
getClass
class:declaredMethods:
getId
getId
setId
setId
Теперь я в замешательстве:
почему в beanInfo есть 2 дескриптора метода для setId, но только один для getId?
почему в объявленном методе есть 2 метода для getId и 2 метода для setId?
Во время отладки у меня есть подписи этих методов при использовании getDeclaredMethods:
[0] = {java.lang.reflect.Method@139}"public java.lang.Long MethodMasking$Item.getId()"
[1] = {java.lang.reflect.Method@446}"public java.io.Serializable MethodMasking$Item.getId()"
[2] = {java.lang.reflect.Method@447}"public void MethodMasking$Item.setId(java.lang.Long)"
[3] = {java.lang.reflect.Method@448}"public void MethodMasking$Item.setId(java.io.Serializable)"
Изменить: После некоторых тестов я обнаружил, что причиной проблемы является использование обобщений в интерфейсе HasId...
Объявленный таким образом, проблема исчезнет: больше нет дублирующих методов.
public interface HasId {
void setId(Long id);
Long getId();
}
public interface Storeable extends HasId {}
2 ответа
Это потому, что компилятор вводит методы моста, когда используются Generics:
некоторое объяснение здесь
Распечатайте больше информации о методах, которые вы получаете: не только их имена, но и списки параметров. Постарайтесь иметь достаточно информации, чтобы различать переопределения и предупреждения. Разница может исходить из этого, но для меня все еще не ясно.
С уважением, Стефан