代码之家  ›  专栏  ›  技术社区  ›  Andriy Drozdyuk Pickels

Java怪异通用返回类型

  •  5
  • Andriy Drozdyuk Pickels  · 技术社区  · 14 年前

    浏览 Guava 我在文件类的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) {
    

    方法如何具有泛型返回类型并为void?

    5 回复  |  直到 14 年前
        1
  •  3
  •   Jesper    14 年前

    我仍然不清楚为什么要在括号内使用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) {
    

    方法如何具有泛型返回类型并为void?

    它没有; <T & GT; 不是“泛型返回类型”,它只是方法的类型参数。你是说这个方法是通用的,而且 T 是类型参数。方法的返回类型为 void .

        2
  •  9
  •   Etaoin    14 年前

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

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

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

    编辑: 为了回答你最新的问题,请记住 <T> 不是 返回类型的一部分:它只是一个指示器 T 是类型参数。所以看看你引用的例子:

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

    那就意味着 fromArrayToCollection 将接受任何数组和集合, 但是 它们必须是相同类型的数组和集合。所以你可以通过 String[] 和A Collection<String> ,或者 Integer[] 和A Collection<Integer> ,但不是 字符串[ ] 和A 集合<integer> . 不管你穿什么类型的 T ,该方法不返回任何内容。

        3
  •  7
  •   ILMTitan    14 年前

    尖括号内的第一个t表示方法本身是泛型的。第二个T是返回类型。t不能是其边界内的任何类型。在这种情况下,t没有界限。

    T将在调用站点确定,在这种情况下,将从lineprocessor<t>参数推断。

        4
  •  3
  •   josefx    14 年前

    不是类级别的泛型,而是方法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");
    

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

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

    该示例调用方法时使用:

    • elementType=字符串
    • listType=数组列表

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

    膨胀端:-)

        5
  •  0
  •   starblue    14 年前

    这是一个通用方法。

    实际上有三个TS,第三个在 LineProcessor<T> 使用方法时指定t。