A compiler that must translate a generic type or method (in any language, not just Java) has two options in principle:
Code Specialization. The compiler generates a new view for each instance of the generic type or method. For example, the compiler will generate code for a list of integers and extra, another code for a list of strings, a list of dates, a list of buffers, etc.
Code exchange. The compiler generates code for only one representation of a generic type or method and displays all instances of the generic type or method for a unique representation, the executing type validates and converts the types when necessary.
Java uses a code sharing method. I believe that C # follows the code specialization method, so all of the code below is logical according to me using C #.
Assuming this piece of Java code:
public class Test { public static void main(String[] args) { Test t = new Test(); String[] newArray = t.toArray(new String[4]); } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) {
The code sharing method will result in this code after erasing the type :
public class Test { public static void main(String[] args) { Test t = new Test();
So my question is:
What is the need to clarify this initial roll?
(T[]) Arrays.copyOf(a, 5, a.getClass());
instead of simple (before erasing styles during coding):
Arrays.copyOf(a, 5, a.getClass());
Is this cast really necessary for the compiler?
Well, Arrays.copyOf returns Object[] and cannot be directly referenced to a more specific type without an explicit downcast.
But could the compiler not make an effort in this case, since it deals with a universal type (return type!)?
Indeed, is it not enough for compilers to use explicit casts to the calling method line ?
(String[])t.toArray(new String[4]);
UPDATED ------------------------------------------- ------ --------------------
Thanks @ ruach for his answer.
Here's an example that proves that explicit listing, even present at compile time, matters:
public static void main(String[] args) { Test t = new Test(); String[] newArray = t.toArray(new String[4]); } public <T> T[] toArray(T[] a) { return (T[]) Arrays.copyOf(a, 5, Object[].class); }
Listing T[] is the only way to warn the user that the cast may not be relevant. And indeed, here we end downcast from Object[] to String[] , which leads to a ClassCastException at runtime.
So, to the extent that "is it not enough for compilers to use explicit casting to the method call line", the answer is:
The developer does not cope with this casting, since it is created automatically at the compilation stage, therefore this runtime function does not warn the user to carefully check his code to ensure security before starting the compilation.
In short, this actor is worth attending.