Java不允许泛型类的内部类数组

Pet*_*rey 15 java arrays generics

我知道你不能创建一个泛型类型的数组,而是你必须求助于黑客攻击.(鉴于Java支持通用数组,而不是它们的创建,我不清楚为什么hack比支持创建泛型数组的Java更好)

而不是写这个

Map.Entry<K, V>[] entries = new Map.Entry<K, V>[numEntries];
Run Code Online (Sandbox Code Playgroud)

你必须写这个

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

不幸的是,如果你有一个嵌套类型的泛型数组,这不起作用

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

    class Inner {
    }
}
Run Code Online (Sandbox Code Playgroud)

最好的工作似乎是

@SuppressWarnings("unchecked")
final Inner[] inners = (Inner[]) Array.newInstance(Inner.class, 16);
Run Code Online (Sandbox Code Playgroud)

这是最"优雅"的解决方案吗?


从内部类看到了通用数组创建编译错误,但这里的解决方案更糟糕恕我直言.

Pau*_*ora 8

请执行下列操作:

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

相当于你的第一个例子,new Outer.Inner[16]但这将隔离未经检查的强制转换并避免原始类型.


new*_*cct 5

您需要意识到的是,您的情况与您描述的第一种情况相同.

Inner是一个Outer泛型类的非静态内部类.这意味着Inner在类型参数的范围内,简单地写作Inner是简短的Outer<E>.Inner.即它可能看不到它,但只是Inner一个参数化类型,就像Map.Entry<K, V>,因为E外部类的类型参数隐式地变成内部类的类型参数.两个问题的解决方案是相同的.

你解决第一个问题的方法是创建一个原始类型的数组,即new Map.Entry[numEntries];.这里的原始类型是什么?不Inner,正如我们已经讨论的那样.相反,您需要显式限定外部类型以访问原始类型:new Outer.Inner[16];.当然,您需要使用强制转换将其强制转换为所需的通用数组类型:

(Inner[])new Outer.Inner[16]
Run Code Online (Sandbox Code Playgroud)

还有另一种方法来创建泛型类型的数组,而不使用原始类型 - 使用通配类型,即new Map.Entry<?, ?>[numEntries];.我们的案例相当于new Outer<?>.Inner[16];.随着演员:

(Inner[])new Outer<?>.Inner[16]
Run Code Online (Sandbox Code Playgroud)