Advantage of generic pattern in java.util.Arrays.copyOf (U [], int, Class <? Extends T []>)

I was browsing in the native java source and found noticeable use of common wildcards in :java.util.Arrays.copyOf(U[], int, Class<? extends T[]>

)


public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

      

I wonder what is the advantage of a generic template Class<? extends T[]>



rather than just a Class<T[]>



parameter newType

, since it T

is not itself declared more explicitly anywhere anyway.
In fact, I rather see a potential flaw, which is detailed here .

+3


source to share


2 answers


Say you have Dog[]

and Animal[]

and want to copy Dog[]

to Animal[]

:

Dog[] dogArray = whatever;
Animal[] animalArray = whatever;
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());

      

animalArray.getClass()

returns a Class<? extends Animal[]>

, so if the method took Class<T[]>

instead of Class<? extends T[]>

(where T

is Animal

), we would have to differentiate it.




Let's say you need to deal with array covariance . You still have Dog[]

and Animal[]

, but now yours Animal[]

can be Subclass[]

for any subclass Subclass

Animal

. You want to copy yours Dog[]

to whatever array of yours Subclass[]

really (maybe something in your hierarchy between Dog

and Animal

, I don't know). This is still

Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());

      

but now it animalArray.getClass()

really isn't Class<Animal[]>

, and it would be completely wrong to do the broadcast. Having it copyOf

, take a is Class<? extends T[]>

much safer.

0


source


For the same reason why this is allowed:

Object[] o = new Integer[1];

      

I am guessing that it is just compatible / consistency compatible.



What if I try to set one position in this array o

to a String? an exception is thrown at runtime: S

This is why bare arrays are broken and you should try to only use them for private fields, otherwise you might be better off than using collections for example List<E>

.

-1


source







All Articles