为什么在外部参数化类中将组件类型作为内部类的数组创建为“通用数组创建”?

时间:2019-01-11 02:45:07

标签: java arrays generics

public class A<T> {
    B[] bs = new B[5];

    private class B {

    }
}

我收到一个编译时错误,指出new B[5]是通用数组创建。我没想到这是因为:

  1. B本身未参数化。
  2. B不是A的类型参数。

考虑到这些原因,为什么new B[5]仍被视为通用数组创建?

2 个答案:

答案 0 :(得分:1)

因为创建B实例的唯一方法(因为它是一个内部类)是使用参数化A的实例。简单修复,更改

private class B

private static class B

答案 1 :(得分:0)

由于BA的一个非静态内部类,因此在A的范围内,不合格的名称B意味着A<T>.B,并且是参数化类型(即使B看起来没有参数化)。 (这很有意义,因为非静态内部类包含对外部类实例的引用;由于对该外部类实例的引用是参数化的,因此内部类实例也必须进行参数化,因此内部类实例“继承”外部类类型参数。)您无法在数组创建表达式中创建参数化类型的数组,因此无法执行new B[5](因为它隐含表示new A<T>.B[5])。

您可以改为创建原始类型的数组。但是请记住,B本身是参数化类型,而不是原始类型。要获取原始类型,您必须使用原始外部类类型显式地对其进行限定:

B[] bs = new A.B[5];

或者您可以创建通配符参数化类型的数组:

B[] bs = (B[])new A<?>.B[5];

在两种情况下,您都会收到未经检查的警告,如果要获取类型为“参数化类型的数组”的变量,例如B[],在Java中这是不可避免的。