What is this line checking? (Object)newType == (Object)Object[].class
It's checking simple equality (likely for the purpose of a micro-optimization, but more on that later).
The unusual casting is necessary because Class<Object[]> (the type of Object[].class) and Class<? extends T[]> are incomparable types. Basically, for an equality comparison with == to compile, one of the sides has to be a subtype or supertype of the other.
I.e. we can't do:
// doesn't compile
// this expression can never evaluate to true
(new Integer(0) == new Float(0f))
The rules for generic types are a bit more complicated and there are a few cases where a comparison doesn't compile, but it may still evaluate to true.
The reason Class<Object[]> is not a supertype of Class<? extends T[]>, despite Object[] being a supertype of all object array types, is that Java generics are invariant without the presence of a wildcard.
Another way to do the comparison would be:
(newType == (Class<? extends Object[]>)Object[].class)
What are the differences between (T[]) new Object[newLength] and (T[]) Array.newInstance(newType.getComponentType(), newLength)?
- new Object[...]creates an array the normal way, of a type that is statically known. Remember, the code has just checked that- T[]is- Object[].
- Array.newInstance(...)uses reflection to dynamically create an array of the- Classtype passed in.
Why Array.newInstance not good enough for both cases?
An operation using reflection is generally slower than its non-reflective counterpart.
The reflection tutorial says:
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
Java SE is filled with micro-optimization like this. The writers of SE try to squeeze everything they can out of it.
But I wouldn't be worried about a performance hit in this case: newInstance and copyOf are HotSpot intrinsics. This means that ideally calls to these methods get replaced with machine-specific assembly. Anecdotally, I ran some tests and found the difference between new Object[...] and Array.newInstance(...) to be negligible. The code in the question is probably a relic, although it may still be useful on less well-equipped JVMs.
Reflection can also be disabled in certain contexts with strict security (such as an applet), but not typically for a normal desktop application.
When should I use this method?
In general, you will probably never use this overload. This overload is only useful if you want to change the type of the array.
- Widening: - Object[] a = Arrays.copyOf(
    new String[] { "hello", "world" }, 3, Object[].class);
a[2] = Character.valueOf('!');
System.out.println(Arrays.toString(a));
 
- Narrowing: - String[] a = Arrays.copyOf(
    new Object[] { "hello", "world" }, 2, String[].class);
System.out.println(String.join(" ", a));
 
It's more typical to use Arrays.copyOf(T[], int).