关于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();
请注意,在某些情况下,上述方法不必须
static的,你可以选择离开了实施
class的名字出来的方法和只使用
interface名称(例如
newList,
newMap)。
有效Java 2nd Edition 的认可 __
这种通用的类型推断
static工厂方法实际上已被 有效Java 2nd Edition所 认可 ;它具有作为书中讨论的 第一 项的独特特权。
以下是 第1项static
_的相关引号 :考虑使用_ 工厂方法而不是构造函数 :
一个 第四 的优点
static工厂方法是它们减少了创建参数化类型实例的详细程度。不幸的是,当调用参数化类的构造函数时,即使它们从上下文中是显而易见的,也必须指定类型参数。这通常需要您连续两次提供类型参数:
Map<String,List<String>> m = new HashMap<String,List<String>>();随着类型参数的长度和复杂性的增加,这种冗余规范很快变得很痛苦。
static但是,对于工厂,编译器可以为您确定类型参数。这称为 类型推断 。例如,
假设 该HashMap提供该static工厂:public static <K,V> HashMap<K,V> newInstance() { return new HashMap<K,V>(); }然后,您可以使用简洁的替代方法替换上面的冗长声明:
Map<String,List<String>> m = HashMap.newInstance();不幸的是,诸如1.6之类的标准集合实现从版本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
请注意,泛型方法调用的显式类型参数化的语法要求是,您 必须 限定类型(if
static)或要在其上调用方法的对象,即使它们不是显式参数化也可以省略。
参考文献
- Angelika Langer的Java泛型常见问题解答
- 什么是通用方法?
- 什么是类型参数推断?
- 什么是显式类型参数规范?
- JLS 8.4.4通用方法
附录:番石榴中的收集工厂方法
应该注意的是,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()工厂方法:
HashMultiSet.create()
,一个Multiset
实现TreeMultimap.create()
,一个Multimap
实现
该库的其余部分还提供了许多非常有用的功能。



