簡體   English   中英

具有泛型類型問題的 JAVA 函數重載

[英]JAVA function overloading with generic type issue

class Test<T>一個方法,它返回一個整數....

public int getIndex(T a) //generic parameter
    {
        return 1; // purposely left simple
    }

使用默認大小 5 實例化的數組: boolean[] arr = new boolean[5]; 現在我有幾個重載函數,故意簡化....

public void add(T a) // generic parameter
    {
        add(getIndex(a));
    }

public void add(int a)
{
        //boolean array with default size 5
        arr[a] = true;
    }
}

在主要:

public static void main(String[] args) {
     Test<Character> test = new Test<Character>();
     test.add('A'); // throws exception
} 

它總是給我arrayOutOfBoundException: 65

據我所知,編譯器只將字符識別為 ASCII 整數值,而不是使用泛型類型參數調用方法,為什么會發生這種情況,我該如何使其工作? 編輯:我在聲明 String 類型的測試時使它工作,因為不涉及 ASCII 轉換。

'A'的類型為char 在 Java 中, char是數字類型,因此可以將其分配給int 此外,當有兩種重載方法 - 一種采用int ,另一種采用裝箱類型Character - 您將獲得int一個:

class Test {
    static void method(int a) {
        System.out.println("int");
    }
    static void method(Character a) {
        System.out.println("Character");
    }
}
> Test.method('A');
int

特別是, 'A'的整數值為 65,因為這是它的 Unicode 值。 因此,您實際上是使用值 65 調用add(int)方法,而不是add(Character)方法,因此是 IOOBE。

要修復它,請在調用方法時顯式轉換為Character ,或者將名稱更改為addByIndexaddByValue以便 Java 不會根據參數類型選擇錯誤的。


要了解 Java為何選擇add(int)方法而不是add(Character) ,需要仔細閱讀 Java 語言規范。 15.12節指定了如何解析方法調用:

第一階段(第 15.12.2.2 節)執行重載解析,不允許裝箱或拆箱轉換,或使用變量 arity 方法調用。 如果在此階段未找到適用的方法,則處理繼續到第二階段。

所以add(int)方法在第一階段匹配,因為從charint轉換不是裝箱或拆箱轉換; 並且在不進行方法解析的第二階段的情況下選擇該方法,在該階段將允許從charCharacter的裝箱轉換。

當由於重載而對調用哪個方法產生歧義時,Java 明確定義了解析順序:

  • 完全符合
  • 隱式和向上轉換
  • 自動裝箱

例如,請參閱此問題以獲取更多信息。

這就是為什么在您的情況下,Java 更喜歡將您的 char 隱式轉換為 int,而不是將 char 裝箱到 Character 並調用泛型重載。

Listremove方法也存在同樣的問題。 考慮:

List<Integer> l = new ARrayList<>();
l.add(10);
l.remove(10); // crash because it calls remove(int) rather than remove(E) with E=Integer

解決方案是不要依賴 autoboxing 例如對於上面的列表,您可以編寫:

l.remove(Integer.valueOf(10));

因此,就您而言:

test.add(Character.valueOf('a'), Character.valueOf('b'));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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