【问题标题】:Java doesn't allow arrays of inner classes for a generic classJava 不允许泛型类的内部类数组
【发布时间】:2013-12-26 19:53:52
【问题描述】:

我知道您不能创建泛型类型的数组,而是必须求助于 hack。 (鉴于 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);

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


我看到了Generic Array Creation Compilation Error From Inner Class,但这里的解决方案更糟糕,恕我直言。

【问题讨论】:

  • 我认为您的第一行和第二行代码有些混淆。 entries 被声明为(单个)Map.Entry 对象,但您正在尝试分配 Map.Entry 对象的数组。还有,entries怎么也可以是数组维度?
  • @TedHopp 感谢您指出这一点。在这两种情况下都是正确的。
  • 恕我直言,链接的解决方案是最好的。它必须是一个数组有什么原因吗?
  • "new (Map.Entry&lt;K, V&gt;) Map.Entry[numEntries];" 应该是 (Map.Entry&lt;K, V&gt;) new Map.Entry[numEntries];

标签: java arrays generics


【解决方案1】:

您可以选择制作内部类static吗?

如果可能的话,您应该能够使用标准方式创建内部类的数组:

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

    static class Inner {
    }
}

【讨论】:

  • 这将通过重构 Inner 以将 Outer 作为参数而不是非静态的来工作。
【解决方案2】:

执行以下操作:

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

与您的第一个示例等效的是new Outer.Inner[16],但这将隔离未经检查的强制转换并避免使用原始类型。

【讨论】:

    【解决方案3】:

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

    Inner 是泛型类Outer 的非静态内部类。这意味着Inner在类型参数的范围内,简单地写InnerOuter&lt;E&gt;.Inner的缩写。即它可能看起来不像,而只是Inner 是一个参数化类型,就像Map.Entry&lt;K, V&gt;,因为外部类的类型参数E 隐含地成为内部类的类型参数。这两个问题的解决方法是一样的。

    您对第一个问题的解决方案是创建一个原始类型的数组,即new Map.Entry[numEntries];。这里的原始类型是什么?不是Inner,正如我们已经讨论过的。相反,您需要明确限定外部类型以访问原始类型:new Outer.Inner[16];。当然,您需要进行强制转换才能将其转换回所需的泛型数组类型:

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

    还有另一种方法可以创建泛型类型的数组,而不使用原始类型——使用通配符类型,即new Map.Entry&lt;?, ?&gt;[numEntries];。我们案例的等价物是new Outer&lt;?&gt;.Inner[16];。与演员:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2016-07-12
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      相关资源
      最近更新 更多