关于参数化类型的泛型工厂方法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 第 2 版的认可
这种泛型类型推断工厂方法实际上得到了有效Java 2nd Edition的认可;它具有独特的特权,成为书中讨论的第一个项目。static
以下是项目 1 中的相关引用:考虑静态
工厂方法而不是构造函数:
工厂方法的第四个优点是它们减少了创建参数化类型实例的详细程度。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 版)没有工厂方法,但您可以将这些方法放在自己的实用程序类中。更重要的是,您可以在自己的参数化类中提供此类工厂。HashMap
static
static
该项目还规定了以下工厂方法的通用命名约定:static
-
getInstance
- 返回由参数描述的实例 [...]
-
newInstance
- Like ,只是它保证返回的每个实例都不同于所有其他实例。getInstance
-
new
Type
- 与 类似,但在工厂方法位于其他类中使用。Type
指示工厂方法返回的对象的类型。newInstance
关于显式类型参数
在大多数情况下,您不必显式提供类型参数,因为 Java 泛型类型推理系统通常可以确定您需要什么。
但是,要提供显式类型参数,语法是将其放在方法名称之前(而不是之后)。下面是使用显式参数从 java.util.Collections
调用泛型方法的示例:<T> List<T> emptyList()
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
请注意,泛型方法调用的显式类型参数化的一个语法怪癖是,您必须限定类型(如果 )或要调用方法的对象,即使如果不是显式参数化,也可以省略它们。static
引用
附录:番石榴的收集工厂方法
应该注意的是,Guava实际上已经为Java Collections Framework中的类型提供了工厂方法:static
来自 main package com.google.common.collect
:
事实上,本着有效的Java 2nd Edition推荐的精神,Guava自己的集合不提供构造函数,而是提供工厂方法:public
static create()
该库的其余部分还提供了许多非常有用的功能。