代码之家  ›  专栏  ›  技术社区  ›  Nick Heiner

Java:泛型语法

  •  16
  • Nick Heiner  · 技术社区  · 14 年前

    此操作用于返回int的列表:

    public List<Integer> GetIListImpl() {
        return new ArrayList<Integer>();
    }
    

    但是如果我想让调用者指定泛型类型呢?就像这样,虽然我不知道怎么做:

    public List<T> GetIListImpl<T>() {
        return new ArrayList<T>();
    }
    

    用法是:

        List<String> = GetIListImpl<String>();
    
    3 回复  |  直到 14 年前
        1
  •  25
  •   Community Jaime Torres    4 年前

    static

    看起来您希望编写方便的工厂方法来实例化泛型集合。

    您可以编写如下通用方法:

    public static <T> List<T> newArrayList() {
        return new ArrayList<T>();
    }
    public static <K,V> Map<K,V> newHashMap() {
        return new HashMap<K,V>();
    }
    

    // absolutely type-safe!!! no compilation warnings at all!!!
    
    List<String> names = newArrayList();
    
    List<Integer> nums = newArrayList();
    
    Map<String, List<String>> map = newHashMap();
    

    请注意,在某些上下文中,不必使用上述方法 静止的 ,您可以选择忽略实现 class 方法之外的名称,并且只使用 interface 姓名(例如。 newList , newMap ).


    来自 有效Java第2版

    这种泛型类型推断 静止的 工厂方法实际上得到了 有效Java第2版 首先

    以下是来自 静止的 工厂方法而不是构造函数

    A 第四 静止的 工厂方法是为了减少创建参数化类型实例的繁琐。

        Map<String,List<String>> m = 
            new HashMap<String,List<String>>();
    

    随着类型参数的长度和复杂性的增加,这种冗余规范很快就会变得痛苦。与 静止的 类型推断 . 例如, 假设 那个 HashMap 静止的

        public static <K,V> HashMap<K,V> newInstance() {
            return new HashMap<K,V>();
        }
    

        Map<String,List<String>> m = HashMap.newInstance();
    

    哈希图 没有 静止的 工厂方法,但您可以将这些方法放在自己的实用程序类中。更重要的是你可以提供 静止的 在您自己的参数化类中的工厂。

    该条款还规定了这些项目的通用命名约定 工厂方法:

    • getInstance -返回由参数[]描述的实例
    • newInstance -就像 获取实例 ,但它保证返回的每个实例都不同于所有其他实例。
    • new Type 新实例 ,但当工厂方法位于不同的类中时使用。 类型 指示工厂方法返回的对象的类型。

    在大多数情况下,您不必显式地提供类型参数,因为Java泛型类型推理系统通常可以确定您需要什么。

    然而,要提供显式类型参数,语法是 之前 方法名称(不是 ). 下面是一个使用显式参数调用泛型方法的示例 <T> List<T> emptyList() java.util.Collections :

    Collections.<String>emptyList();
    // Collections.emptyList<String>(); // DOES NOT COMPILE
    

    请注意,泛型方法调用的显式类型参数化的一个语法怪癖是 限定类型(如果 静止的 )或者调用方法的对象,即使它们不是显式的参数化,也可以省略。


    工具书类


    附录:番石榴的工厂收集方法

    应该指出的是 Guava 事实上已经提供了 静止的 中类型的工厂方法 Java Collections Framework :

    从主要 package com.google.common.collect

    建议,番石榴自己的收藏不提供 public static create() 工厂方法:

    库的其余部分还提供了许多非常有用的功能。

        2
  •  8
  •   Colin Hebert    14 年前

    语法应该是

    public static <T> List<T> getIListImpl() {
        return new ArrayList<T>();
    }
    

    用法更像:

    MyClass.<Integer>getIListImpl();
    
        3
  •  1
  •   josefx    14 年前

    首先必须在方法上指定泛型类型,而不是类级别。

    class Test
    {
        public static <T> List<T> getListImpl() {
            return new ArrayList<T>();
        }
    }
    

    查看泛型类型参数的位置,它位于方法名称之前。对于类,它位于类名后面。因此,与其在方法名之后添加泛型类型,不如这样调用它

    List<Integer> l = Test.<Integer>getListImpl()
    

    必须使用类名或实例来调用它。编译器不喜欢以下内容:

    List<Integer> l = <Integer>getListImpl()
    

    有时它在没有泛型类型的情况下工作

    List<Integer> l = getListImpl()
    

    这里的比较类和方法是泛型的

    class Test<T>{}//Generic after class name
    T<Integer> t = new T<Integer>();
    void <T> methName(){}//Generic before method name
    t.<Integer>methName();