关于参数化类型的通用static
工厂方法
看起来您想编写方便的工厂方法来实例化泛型集合。
您可以编写以下通用方法:
public static <T> List<T> newArrayList() {
return new ArrayList<T>();
}
public static <K,V> Map<K,V> newHashMap() {
return new HashMap<K,V>();
}
然后你可以简单地写:
List<String> names = newArrayList();
List<Integer> nums = newArrayList();
Map<String, List<String>> map = newHashMap();
请注意,在某些情况下,上述方法不必是“静态的”,您可以选择在方法中省略实现“class”名称,仅使用“interface”名称(例如,“newList”,“newMap”)。
《Effective Java第二版》的认可
这种泛型类型推断的static
工厂方法实际上得到了《Effective Java第二版》的认可;它有着独特的特权,成为了该书讨论的第一条内容。
以下是来自第1条:考虑使用static
工厂方法代替构造器的相关引用:
A fourth advantage of static
factory methods is that they reduce the verbosity of creating parameterized type instances.
When you invoke the constructor of a parameterized class, unfortunately you must specify the type parameters even if they're obvious from context. This typically requires you to provide the type parameters twice in quick succession:
Map<String,List<String>> m =
new HashMap<String,List<String>>();
This redundant specification quickly becomes painful as the length and complexity of the type parameters increase. With static
factories, however, the compiler can figure out the type parameters for you. This is known as type inference. For example, suppose that HashMap
provided this static
factory:
public static <K,V> HashMap<K,V> newInstance() {
return new HashMap<K,V>();
}
Then you could replace the wordy declaration above with this succinct alternative:
Map<String,List<String>> m = HashMap.newInstance()
Unfortunately the standard collection implementations such as HashMap
do not have static
factory methods as of release 1.6, but you can put these methods in your own utility class. More importantly you can provide such static
factories in your own parameterized classes.
该项还规定了这些static
工厂方法的常见命名约定:
getInstance
- 返回由参数描述的实例[...]。
newInstance
- 类似于getInstance
,但它保证返回的每个实例都与所有其他实例不同。
new
Type
- 类似于newInstance
,但在工厂方法位于不同类时使用。Type
指示工厂方法返回的对象类型。
关于显式类型参数
在大多数情况下,您不必显式提供类型参数,因为Java泛型类型推断系统通常可以推断出您需要的内容。
尽管如此,如果要提供显式类型参数,则语法是将其放在方法名称之前(而不是之后)。以下是使用显式参数调用java.util.Collections
中的泛型方法<T> List<T> emptyList()
的示例:
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
注意,泛型方法调用的显式类型参数化的语法怪癖是,即使它们在非显式参数化时可以省略,但您
必须限定类型(如果是
static
)或调用方法的对象。请注意保留"{{"和"}}"和HTML标签。
参考文献
附录:Guava提供的集合工厂方法
需要注意的是,Guava实际上已经为Java Collections Framework中的类型提供了static
工厂方法:
从主要的package com.google.common.collect
中:
实际上,按照《Effective Java第二版》的建议,Guava自己的集合不提供公共构造函数,而是提供静态的
create()
工厂方法:
此外,该库还提供了许多非常有用的功能。
GetIListImpl
- 这看起来像是C#的命名惯例。在Java中,可能会用getListImpl
。 - polygenelubricants