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 .
source to share
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.
source to share
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>
.
source to share