Beny Bosko February 2016

Java / Generics / Array problems

I would like to understand the relationship between generics and arrays finally, so i will provide an example which is inconsisent for me, based on an ArrayList<T> :

Object[] elementData = new Object[size];

This is where elements of the generic list are stored.

public void add(T element){ elementData[size++] = element; }

public T get(int index) { return (T)elementData[index] }

Completely works. I can get out the underlying <T> objects, however the array which contains the references to these objects is Object.

In contrast to this:

public Object[] toArray()
{       
    Object[] result = new Object[size];

    for(int i = 0;i<size;i++)
    {
        result[i] = elementData[i];
    }

    return result;
}

I cannot cast the elements in the returned array to their real type, however the whole set up is the same: an Object array which contains references to <T> objects. I got ClassCastException error, when trying to cast the elements to their real type.

Answers


Ranjeet February 2016

You can cast the elements in the returned array to their real type. But you cannot cast the array to T[ ]


Ferrybig February 2016

If you look into the Collection interface, you see that there are 2 toArray() methods:

  • Object[] toArray()

    Returns an array containing all of the elements in this collection.

  • <T> T[] toArray(T[] a)

    Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.

The reason for that is that you cannot make generic arrays, so you only return a Object[].

Making a generic method of your toArray() is simple:

public <T> T[] toArray(T[] arr)
{       
    T[] result = arr.size == size ? arr : (T[])java.lang.reflect.Array
              .newInstance(arr.getClass().getComponentType(), size);

    for(int i = 0;i<size;i++)
    {
        result[i] = elementData[i];
    }

    return result;
}


pdem February 2016

Arrays in java existed before java 5, which introduces Generics. So Arrays doesn't rely on generics, this is why we often use Collections instead of arrays in API. So Collection can eventually be casted to Collection, but Object[] cannot be casted to another array T[], it would be another incompatible type.


Radu Ionescu February 2016

I think it has to do with the fact that arrays are covariant and thus you are allowed to cast from T[] to Object[], since Object can do anything T can, but the other way around does not make sense, Object can not do everything T can.


newacct February 2016

Arrays know their component type at runtime. Therefore, to create an array, you need to provide the component type at runtime. However, in your case you don't know T at runtime. Therefore, you cannot create something that is truly a T[]. You can only return Object[], or rely on someone giving you something with which you can get the type T from at runtime.

Post Status

Asked in February 2016
Viewed 3,933 times
Voted 4
Answered 5 times

Search




Leave an answer