简体   繁体   English

通用数组和通用值有什么区别?

[英]What's the difference between the generic array and the generic value?

public class Array<T> {
    private Object[] array;
    public Array(int sz) {
        array = new Object[sz];
    }
    // ....
    public T get(int index) { return (T)array[index]; }
    public T[] rep() { return (T[])array; } 
}

Why does the compiler say that (T[])array is unchecked cast, and then ClassCastException is thrown when I use the rep() method? 为什么编译器说(T[])array是未经检查的强制转换,然后在我使用rep()方法时引发ClassCastException And why is this exception not thrown when I use the get() method()? 当我使用get()方法()时为什么不抛出此异常?

why is this exception not thrown when I use the get() method()? 为什么在我使用get()方法()时未引发此异常?

There are two reasons for this : 有两个原因 :

  1. Assuming that no elements were added to array in your program, the array is going to be initialized with sz number of null values.. The statement (T)array[index] is trying to cast a null into a T (where T essentially gets replace by Object through type erasure). 假设您的程序中未向array添加任何元素,则将使用sznull值初始化array 。. (T)array[index]语句试图将null转换为T (其中T本质上是通过类型擦除替换为Object )。 A null can be cast into any type so this is not an issue. 可以将null强制转换为任何类型,因此这不是问题。
  2. Assuming that some elements are added to array in your program, the only way that the statement (T)array[index] will work without any issues is if the element at position index is of the same type or a subtype used for instantiating Array (eg Array<Number> arr = new Array<Number> and arr[index] is 1. This won't be an issue; however, try inserting a String at arr[index] and you are bound to get a ClassCastException from the get method as well) 假设您的程序中将一些元素添加到array中,则语句(T)array[index]可以正常工作的唯一方法是,位置index处的元素是否是用于实例化Array的相同类型或子类型(例如Array<Number> arr = new Array<Number>arr[index]为1。这不是问题;但是,尝试在arr[index]处插入一个String ,您肯定会从get ClassCastException 。方法)

Why does the compiler say that (T[])array is unchecked cast, and then ClassCastException is thrown when I use the rep() 为什么编译器说(T [])数组是未经检查的强制转换,然后在我使用rep()时抛出ClassCastException

The only way for you to get a ClassCastException is that the type represented by T is not the same as the type of elements that array can hold. 获得ClassCastException的唯一方法是T表示的类型与array可以容纳的元素的类型不同。 For example, doing something as follows will result in a ClassCastException : 例如,执行以下操作将导致ClassCastException

Array<Integer> a = new Array<Integer>();
Integer[] intArray = a.rep();//ClassCastException

Here, T[] represents an Integer[] so there are no issues in compiling the code; 在这里, T[]表示一个Integer[]因此在编译代码时没有问题。 however, at runtime, array is of type Object[] . 但是,在运行时, array的类型为Object[] An array of Object cannot be downcast to an array of Integer . Object数组不能向下转换为Integer数组。 It would also help to know that arrays are dynamically created by the JVM unlike other classes. 知道数组是由JVM与其他类不同的动态创建的,这也将有所帮助。

One way to fix this would be to instantiate Array as Array<Object> arr = new Array<Object> . 解决此问题的一种方法是将Array实例化为Array<Object> arr = new Array<Object>

In get() , you just care about the actual runtime type of the elements inside the array, which I assume are right because you have some method that puts only T s into the array. get() ,您只关心数组中元素的实际运行时类型,我认为这是正确的,因为您有某种方法只能将T放入数组中。 The array's actual runtime type doesn't matter. 数组的实际运行时类型无关紧要。

In rep() , you care about the array object's actual runtime type, because you are casting it to T[] . rep() ,您关心数组对象的实际运行时类型,因为您将其强制转换为T[] You created the array with actual runtime type Object[] , so the cast to T[] will always be incorrect unless T happens to be Object . 您使用实际的运行时类型Object[]创建了数组,因此,除非T恰好是Object否则对T[]的强制转换将始终不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM