Java 创建类的泛型类型的数组

Java 创建类的泛型类型的数组,java,generics,casting,runtime-error,Java,Generics,Casting,Runtime Error,对于类,我们必须在java中实现数据结构,而不使用默认情况下已经实现的数据结构,所以我不能使用列表。以前有一些情况需要创建泛型类型的数组T,以下操作没有问题: class Test<T> { private T[] array; @SuppressWarnings("unchecked") public Test(int sz) { array = (T[]) new Object[sz]; } public static void main(Stri

对于类,我们必须在java中实现数据结构,而不使用默认情况下已经实现的数据结构,所以我不能使用
列表。以前有一些情况需要创建泛型类型的数组
T
,以下操作没有问题:

class Test<T> {
  private T[] array;

  @SuppressWarnings("unchecked")
  public Test(int sz) {
    array = (T[]) new Object[sz];
  }

  public static void main(String[] args) {
    Test test = new Test(1);
  }
}
对于第二种情况,可以做些什么?

试试以下方法:

public class Thing<T> {
}

class Test<T> {
    private Thing<T>[] array;

    @SuppressWarnings("unchecked")
    public Test(int sz) {
        array = (Thing[]) Array.newInstance(Thing.class, sz);
    }

    public static void main(String[] args) {
        Test<Object> test = new Test<>(1);
    }
}
公共类的东西{
}
课堂测试{
私有事物[]数组;
@抑制警告(“未选中”)
公共测试(int sz){
array=(Thing[])array.newInstance(Thing.class,sz);
}
公共静态void main(字符串[]args){
测试=新测试(1);
}
}

您可以进一步引用您正在尝试将
对象的列表
强制转换为
对象
,而
对象
不是该对象,因此它将不起作用

你面临的问题是

因此,相反,创建一个原始类型
Thing[]
的数组,并将其转换为泛型类型
Thing[]
,考虑到无论如何都会发生这种情况,这在本例中是可以的

class Thing<T> {
}

class Test<T> {
    private Thing<T>[] array;

    @SuppressWarnings("unchecked")
    public Test(int sz) {
        array = (Thing<T>[]) new Thing[sz];
    }

    public static void main(String[] args) {
        Test<Object> test = new Test<>(1);
    }
}
类的东西{
}
课堂测试{
私有事物[]数组;
@抑制警告(“未选中”)
公共测试(int sz){
数组=(Thing[])新事物[sz];
}
公共静态void main(字符串[]args){
测试=新测试(1);
}
}

当您将
对象[]
投射到
T[]
时,这是一个谎言,因为如果
T
不是
对象
,这是不正确的。但是,它不会在类内部导致类强制转换异常,因为类的内部在类型变量
T
的范围内,因此在运行时将变量
数组的类型
T[]
擦除为
Object[]
,因此将
Object[]
强制转换为它不会失败(尽管如果以某种方式将数组作为type
T[]
公开给类外部,外部调用方可能会得到类强制转换异常)

如果
T
有一个类似
的上限,那么
T[]
的擦除将是
MyClass[]
,因此将
Object[]
强制转换到它会立即抛出类强制转换异常,而您必须执行
new MyClass[sz]
才能使它不立即抛出类强制转换异常


这里,变量的类型是
Thing[]
,其擦除是
Thing[]
。因此您必须使用
newthing[sz]
创建一个数组,这样它就不会抛出类强制转换异常。

而不是执行
array=(Thing[])new Object[sz];
,为什么不能直接执行
array=newthing[sz]
?@AshishkumarSingh我可以……但是为什么?这回答了你的问题吗?@Priyam我相信没有。这个问题似乎是要创建一个类型为
T
的数组,而不是类型为
SomeClass
@CarlaCvekla的数组。你尝试的施法相当于“这个对象数组实际上是一个事物数组”,JVM然后对其说“不,不是”,并抛出一个
ClassCastException
。因此您将使用
newthing[sz]
,因为它是正确的。是否有任何理由将
newthing[sz]
强制转换为
Thing[]
不过?即使没有强制转换,它似乎也能工作。@CarlaCvekla,不,本质上是一样的。在一种情况下,它是一个未经检查的强制转换,而在另一种情况下,它是一个未经检查的赋值。
class Thing<T> {
}

class Test<T> {
    private Thing<T>[] array;

    @SuppressWarnings("unchecked")
    public Test(int sz) {
        array = (Thing<T>[]) new Thing[sz];
    }

    public static void main(String[] args) {
        Test<Object> test = new Test<>(1);
    }
}