簡體   English   中英

Java不允許泛型類的內部類數組

[英]Java doesn't allow arrays of inner classes for a generic class

我知道你不能創建一個泛型類型的數組,而是你必須求助於黑客攻擊。 (鑒於Java支持通用數組,而不是它們的創建,我不清楚為什么hack比支持創建泛型數組的Java更好)

而不是寫這個

Map.Entry<K, V>[] entries = new Map.Entry<K, V>[numEntries];

你必須寫這個

@SuppressWarnings("unchecked")
Map.Entry<K, V>[] entries = (Map.Entry<K, V>) new Map.Entry[numEntries];

不幸的是,如果你有一個嵌套類型的泛型數組,這不起作用

public class Outer<E> {
    final Inner[] inners = new Inner[16]; // Generic array creation

    class Inner {
    }
}

最好的工作似乎是

@SuppressWarnings("unchecked")
final Inner[] inners = (Inner[]) Array.newInstance(Inner.class, 16);

這是最“優雅”的解決方案嗎?


從內部類看到了通用數組創建編譯錯誤,但這里的解決方案更糟糕恕我直言。

請執行下列操作:

@SuppressWarnings("unchecked")
final Inner[] inners = (Inner[])new Outer<?>.Inner[16];

與你的第一個例子相同的是new Outer.Inner[16]但是這將隔離未經檢查的強制轉換並避免原始類型。

您需要意識到的是,您的情況與您描述的第一種情況相同。

InnerOuter的非靜態內部類,是泛型類。 這意味着Inner屬於type參數的范圍,而簡單地寫InnerOuter<E>.Inner縮寫。 即它可能看不到它,但簡單地說Inner是一個參數化類型,就像Map.Entry<K, V> ,因為外部類的類型參數E隱式地變成了內部類的類型參數。 兩個問題的解決方案是相同的。

你解決第一個問題的方法是創建一個原始類型的數組,即new Map.Entry[numEntries]; 這里的原始類型是什么? 正如我們已經討論的那樣,不是Inner 相反,您需要明確限定外部類型以訪問原始類型: new Outer.Inner[16]; 當然,您需要使用強制轉換將其強制轉換為所需的通用數組類型:

(Inner[])new Outer.Inner[16]

還有另一種創建泛型類型數組的方法,不使用原始類型 - 使用通配類型,即new Map.Entry<?, ?>[numEntries]; 我們案例的等價物是new Outer<?>.Inner[16]; 隨着演員:

(Inner[])new Outer<?>.Inner[16]

你可以選擇讓內部類static嗎?

如果可能,您可以使用標准方式創建內部類的數組:

public class Outer<E> {
    final Inner[] inners = new Inner[16]; // works

    static class Inner {
    }
}

暫無
暫無

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

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