Java奇怪的泛型返回类型

时间:2010-05-20 19:10:15

标签: java generics

浏览Guava库我在Files类的readLines方法中看到了这个奇怪的签名:

public static <T> T readLines(File file,
                          Charset charset,
                          LineProcessor<T> callback)

我对java中的泛型有点了解,但这让我感到困惑。

双T的含义是什么?为什么第一个用斜角括号?

更新:感谢您的回答。我仍然不清楚为什么我应该在括号内使用T.为什么例如它不能只是:

 public static <> T readLines()

 pulibc static <K> T readLines()

或者java语法是否规定必须使用相同的字母?

现在this更加凶悍:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) {

一个方法如何具有泛型返回类型并且无效?

5 个答案:

答案 0 :(得分:9)

这是泛型方法 - T被称为类型参数,可以表示任何类型。所以,如果我有一个带有此签名的方法:

public <T> T foo(T[] bar)

我可以在任何数组上调用它,它将返回一个相同类型的单个对象。如果我传递一个String数组,我将返回一个String,依此类推。更多信息in the Sun tutorials for "generic methods".

修改:要回答您更新的问题,请注意第一个<T> 不是返回类型的一部分:它只是一个指标T是一个类型参数。那么看看你引用的例子:

static <T> void fromArrayToCollection(T[] a, Collection<T> c)

这只意味着fromArrayToCollection将接受任何数组和任何集合,它们必须是相同类型的数组和集合。因此,您可以传递String[]Collection<String>,或Integer[]Collection<Integer>,但不能传递String[]Collection<Integer>。无论您为T输入什么类型,该方法都不会返回任何内容。

答案 1 :(得分:7)

尖括号内的第一个T表示方法本身是通用的。第二个T是返回类型。 T可以是其范围内的任何类型。在这种情况下,T没有界限。

将在呼叫站点确定T,并且在这种情况下,从LineProcessor&lt; T&gt;推断出。参数。

答案 2 :(得分:3)

只有readLines方法使用泛型,而不是类级别的泛型。

  • 第一个<T>声明方法
  • 使用的泛型类型
  • 以下T是返回类型。

第一个使用与泛型类相同的语法来声明泛型类型。相反,你可以写

class Generic <T> 
{
public static T readLines(File file,
                          Charset charset,
                          LineProcessor<T> callback)
}

然而,这将使该类的所有实例都通用。

扩展示例:

public static <ElementType,ListType extends List<ElementType>> ListType add(ListType list,ElementType elem)
{
   list.add(elem);
   return list;
}
ArrayList<String> = add(add(new ArrayList<String>(),"Hello"),"World");

该方法将给定元素添加到List并返回List 该方法对列表的元素使用两个泛型类型1,对列表本身使用一个类型 使用的名称没有什么特别之处,对于泛型类型使用T就像使用i作为整数一样。

  • ElementType是用于通用元素类型的名称(可以使用任何有效的变量名称/标识符)
  • ListType是通用列表Type的名称,使用的类必须为ElementType扩展/实现List。

该示例使用以下方法调用该方法:

  • ElementType = String
  • ListType = ArrayList

这将导致
public static ArrayList<String> add(ArrayList<String> list, String elem)

膨胀结束: - )

答案 3 :(得分:3)

  
    

我仍然不清楚为什么我应该在括号内使用T.为什么例如它不能只是:

  
 public static <> T readLines()
     

 public static <K> T readLines()
     

或者java语法是否规定必须使用相同的字母?

<T><K>是类型参数。如果你写<K> T,那么T不是一个类型参数 - 而是你正在使用特定的class T。如果您没有在范围内命名为T的类,则无效。

  

现在这甚至更加严峻:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
     

一个方法如何具有泛型返回类型并且无效?

没有; <T>不是“泛型返回类型”,它只是方法的类型参数。您说该方法是通用的,T是类型参数。方法的返回类型为void

答案 4 :(得分:0)

这是一种通用方法。

实际上有三个Ts,LineProcessor<T>上的第三个在你使用这个方法时指定了T.