[英]Differences between BeanInfo:methodDescriptors and class:declaredMethods : multiple methods with same name and method masking
當試圖在運行時為某些屬性獲取JPA注釋時,我遇到了這個問題。 我無法解釋原因。
PS:在與Spring的調試會話之后,我找到了這個問題的解釋:編譯器在編譯時引入的橋接方法。 請看我自己對這個問題的回答..
以下是復制問題的示例源代碼(實際代碼的簡化版本)。
import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.MethodDescriptor; import 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中有4個方法描述符用於setId但只有一個用於getId?
為什么在聲明的方法中有4個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 {}
這是因為編譯器在使用泛型時引入了橋接方法 :
這里有一些解釋
打印出有關您收到的方法的更多信息:不僅是他們的名字,還包括參數列表。 嘗試獲取足夠的信息來區分覆蓋和averloads。 差異可能來自於此,但對我來說仍然不明確。
此致,Stéphane
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.