这可以返回一个int列表:
public List<Integer> GetIListImpl() {
return new ArrayList<Integer>();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想让调用者指定泛型类型呢?像这样的东西,虽然从语法上来说我不知道怎么做:
public List<T> GetIListImpl<T>() {
return new ArrayList<T>();
}
Run Code Online (Sandbox Code Playgroud)
用法是:
List<String> = GetIListImpl<String>();
Run Code Online (Sandbox Code Playgroud)
pol*_*nts 25
static参数化类型的通用工厂方法看起来您想要编写方便的工厂方法来实例化泛型集合.
您可以编写如下通用方法:
public static <T> List<T> newArrayList() {
return new ArrayList<T>();
}
public static <K,V> Map<K,V> newHashMap() {
return new HashMap<K,V>();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以简单地写:
// absolutely type-safe!!! no compilation warnings at all!!!
List<String> names = newArrayList();
List<Integer> nums = newArrayList();
Map<String, List<String>> map = newHashMap();
Run Code Online (Sandbox Code Playgroud)
请注意,在某些情况下,上述方法不必如此static,您可以选择class从方法中省略实现名称,并仅使用interface名称(例如newList,newMap).
这种通用类型推断static工厂方法实际上得到了Effective Java 2nd Edition的认可 ; 它拥有成为本书中讨论的第一个项目的独特特权.
以下是第1项static中的相关引用:考虑工厂方法而不是构造函数:
一个第四的优点
static工厂方法是它们减少了创建参数化类型实例的详细程度.当您调用参数化类的构造函数时,遗憾的是您必须指定类型参数,即使它们在上下文中是显而易见的.这通常要求您快速连续提供两次类型参数:
Run Code Online (Sandbox Code Playgroud)Map<String,List<String>> m = new HashMap<String,List<String>>();随着类型参数的长度和复杂性的增加,这种冗余规范很快变得痛苦.
static但是,对于工厂,编译器可以为您计算类型参数.这称为类型推断.例如,假设该HashMap提供该static工厂:Run Code Online (Sandbox Code Playgroud)public static <K,V> HashMap<K,V> newInstance() { return new HashMap<K,V>(); }然后你可以用这个简洁的替代方案替换上面的罗嗦声明:
Run Code Online (Sandbox Code Playgroud)Map<String,List<String>> m = HashMap.newInstance();不幸的是,标准集合实现(如1.6版本中
HashMap没有static工厂方法),但您可以将这些方法放在您自己的实用程序类中.更重要的是,您可以static在自己的参数化类中提供此类工厂.
该项还规定了这些static工厂方法的通用命名约定:
getInstance- 返回参数[...]描述的实例newInstance- 比如getInstance,除了它保证返回的每个实例都与其他实例不同.newType- 比如newInstance,但是当工厂方法属于不同的类时使用.Type表示工厂方法返回的对象类型.
在大多数情况下,您不必显式提供类型参数,因为Java泛型类型推断系统通常可以找出您需要的内容.
然而,要提供显式类型参数,语法是将其放在方法名称之前(而不是之后).这里是有明确参数的泛型方法调用的一个例子<T> List<T> emptyList()来自java.util.Collections:
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
Run Code Online (Sandbox Code Playgroud)
请注意,泛型方法调用的显式类型参数化的语法怪癖是您必须限定类型(if static)或调用该方法的对象,即使它们不是显式参数化也可以省略.
应该注意的是,Guava实际上已经为Java Collections Framework中static的类型提供了工厂方法:
从主要package com.google.common.collect:
Lists.newArrayList(),newLinkedList(),...Sets.newHashSet(),newTreeSet(),newEnumSet(…),...Maps.newHashMap(),newTreeMap(),newEnumMap(…),...事实上,根据Effective Java 2nd Edition推荐的精神,Guava自己的集合不提供public构造函数,而是提供static create()工厂方法:
库的其余部分还提供了许多非常有用的功能.
语法是
public static <T> List<T> getIListImpl() {
return new ArrayList<T>();
}
Run Code Online (Sandbox Code Playgroud)
你很亲密
用法更像是:
MyClass.<Integer>getIListImpl();
Run Code Online (Sandbox Code Playgroud)