簡體   English   中英

BeanInfo:methodDescriptors和類之間的差異:declaredMethods:具有相同名稱和方法屏蔽的多個方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM