简体   繁体   中英

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? And why is this exception not thrown when I use the get() method()?

why is this exception not thrown when I use the get() method()?

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). A null can be cast into any type so this is not an issue.
  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)

Why does the compiler say that (T[])array is unchecked cast, and then ClassCastException is thrown when I use the rep()

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. For example, doing something as follows will result in a 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; however, at runtime, array is of type Object[] . An array of Object cannot be downcast to an array of Integer . It would also help to know that arrays are dynamically created by the JVM unlike other classes.

One way to fix this would be to instantiate Array as 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. 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[] . You created the array with actual runtime type Object[] , so the cast to T[] will always be incorrect unless T happens to be Object .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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