I'm using Eclipse and when I navigate the disassemble of List.class I see this:
<T> T[] toArray(T[] a);
What does the leading
<T>
actually mean here? Is it part of return type? I guess the return value isT[]
.In what scenario does a function need to declare like
<T> T[]
as function signature?
CodePudding user response:
This defines a method where some types aren't fixed, but generic.
A non-generic version of that method would e.g. be
String[] toArray(String[] a);
meaning that you provide a String[]
array and get a String[]
array.
The given method replaces the String
with a generic type T
, meaning that the result type now depends on the type provided (*), that the resulting array type is the same as the type provided as the array parameter.
The array type relevant here need not (exactly) correspond to the generic type of the List as a whole (the E
in List<E>
), but instead is specific for just this method, so it must be declared with this method, and that's the <T>
in <T> T[] toArray(T[] a);
So, breaking down the <T> T[] toArray(T[] a);
into its parts:
<T>
declares that the following method has some method-specific generic typeT
.T[]
says the the return value is an array of this generic type.toArray(...)
names the method.T[] a
declares that the method expects an array-typed parameter.
With Java generics, the compiler needs to find the specific type that replaces T
in any given method invocation like
??? myArray = myList.toArray(new String[17]);
Here, the argument gives the information: a String[]
array is provided, a T[]
array is expected, so T
must be String
, and now the compiler knows that in the result type T[]
the T
has to be replaced with String
as well, giving a String[]
result type, meaning that ???
must be String[]
or compatible, otherwise you get a compiler error.
Besides this deduction-based type matching, there is also a (rarely used) syntax for explicitly specifying the generic type. That would be
String[] myArray = myList.<String>toArray(new String[17]);
The <String>
infix explicitly tells the compiler the T
replacement. In most cases, this explicit specification is redundant, so you'll hardly ever see this syntax in real-world code.
(*) Java generics are completely evaluated at compile time, so the generic effects of the declaration are only based on the types as the compiler sees them. So, e.g. in
Object[] myObjectArray = new String[0];
??? myResultArray = myList.toArray(myObjectArray);
the ???
has to be Object[]
, although at runtime, a String[]
array will be produced.
CodePudding user response:
Remember that the idea behind generics is to parameterise a class on type and that you specify that type when you instantiate the class. <T>
is the type parameter - that is you write that to say that this class/method is parameterised on some type T
specified at run time.