Java泛型:<T> T[] toArray(T[] a)中的第一个“T”是什么意思?

Tro*_*yvs 0 java generics types declaration function

我正在使用 Eclipse,当我导航 List.class 的反汇编时,我看到了这个:

<T> T[] toArray(T[] a);
Run Code Online (Sandbox Code Playgroud)
  1. 这里的领先<T>实际上意味着什么?它是返回类型的一部分吗?我猜返回值是T[].

  2. 在什么情况下函数需要声明 like<T> T[]作为函数签名?

Ral*_*off 6

这定义了一种方法,其中某些类型不是固定的,而是通用的。

该方法的非通用版本例如是

String[] toArray(String[] a);
Run Code Online (Sandbox Code Playgroud)

这意味着您提供一个String[]数组并获取一个String[]数组。

给定的方法将 替换String为泛型类型T,这意味着结果类型现在取决于提供的类型 (*),即生成的数组类型与作为数组参数提供的类型相同。

这里相关的数组类型不需要(完全)对应于整个 List 的泛型类型( in EList<E>,而是特定于此方法,因此必须使用此方法声明它,这就是<T>in<T> T[] toArray(T[] a);

因此,将其分解<T> T[] toArray(T[] a);为几个部分:

  • <T>声明以下方法具有某些特定于方法的泛型类型T
  • T[]表示返回值是该泛型类型的数组。
  • toArray(...)为方法命名。
  • T[] a声明该方法需要一个数组类型的参数。

对于 Java 泛型,编译器需要找到T在任何给定方法调用中替换的特定类型,例如

??? myArray = myList.toArray(new String[17]);
Run Code Online (Sandbox Code Playgroud)

这里,参数给出了信息:String[]提供了一个数组,T[]需要一个数组,所以T必须是String,现在编译器知道在结果类型中也T[]必须T替换为String,给出一个String[]结果类型,这意味着???必须是String[]或兼容,否则会出现编译器错误。

除了这种基于推导的类型匹配之外,还有一种(很少使用的)语法用于显式指定泛型类型。那将是

String[] myArray = myList.<String>toArray(new String[17]);
Run Code Online (Sandbox Code Playgroud)

<String>缀明确告诉编译器T替换。在大多数情况下,这种显式规范是多余的,因此您几乎不会在实际代码中看到这种语法。

(*) Java 泛型在编译时完全评估,因此声明的泛型效果仅基于编译器看到的类型。所以,例如在

Object[] myObjectArray = new String[0];
??? myResultArray = myList.toArray(myObjectArray);
Run Code Online (Sandbox Code Playgroud)

必须???Object[],尽管在运行时,String[]将生成一个数组。