通用数组初始化

Generic Array initialisation

我已经阅读了不同的文章,其中讨论了为什么我们不能在 java 中创建泛型数组,但我仍然不太明白为什么。

比如这个post, it assumed if generic array initialisation is possible, there will be casting issue after erasure. You can find the details in section 2. Considerations When Using Generic Arrays。简单来说,泛型数组擦除后变成Object Array,如果泛型类型是String,java将无法将Object[]转换为String[]。

但是,我创建了一个具有简单功能的通用 class,

// Test.java
public class Test<T> {
    public T[] getStrArr(T[] arr) {
        return arr;
    }
}

//Main.java
public static void main(String[] args) {
       Test<String> test = new Test<>();
        String[] strArr = test.getStrArr(new String[]{"A", "B", "C"});
}

擦除后,getStringArr 应该 return Object[],并且可以毫无问题地转换为 String[]。

另一个 Whosebug post 指出:

数组(与泛型不同)在运行时包含有关其组件类型的信息。所以在创建数组的时候一定要知道组件类型。由于在运行时不知道 T 是什么,因此无法创建数组。

但是擦除会将T变成Object类型,所以编译器可以创建Object类型的数组。

其他帖子也有类似的解释,但不能真正解决我的疑惑。

请帮忙!

After erasure, the getStringArr should return Object[], and it is able to cast to String[] without any problem.

Return getStrArr 的类型,在类型擦除之后,将是 Object[] 但是,在您的代码中,它返回 arr 类型 String[]。这就是为什么您的代码中没有 ClassCastException

考虑以下方法(假设允许泛型数组):

public T[] foo() {
    return new T[5];                  
} 

类型擦除后,new T[5] 将替换为 new Object[5]。现在,如果调用代码将此方法调用为:

String[] strArr = obj.foo();

它会导致 ClassCastException 因为 Object[] 不能转换为 String[].