泛型实例创建的类型推理
只要编译器可以从上下文中推断类型参数,就可以用一组空的类型参数(<>)替换泛型类参数。
// java 7之前
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
//java7之后,可以用一组空的类型参数(<>)替换构造函数的参数化类型:
Map<String, List<String>> myMap = new HashMap<>();
JavaSE7只支持有限的类型推断; 只有当构造函数的参数化类型从上下文中明显可见时,才能使用类型推断。 例如,以下示例无法编译:
List<String> list = new ArrayList<>();
list.add("A");
// 以下不可以<br/>
list.addAll(new ArrayList<>());
//改成这样才可以<br/>
List<? extends String> list2 = new ArrayList<>();
list.addAll(list2);
请注意,钻石通常在方法调用中工作;但是,建议您主要将钻石用于变量声明。
泛型和非泛型类的类型推理和泛型构造函数
注意,构造函数在泛型和非泛型类中都可以是泛型的(换句话说,声明它们自己的形式类型参数)。考虑下面的例子 ``` class MyClass { MyClass(T t) { // ... } } ``` 考虑以下MyClass类的实例化,该类在Java SE 7和以前的版本中有效: ``` new MyClass("") ``` 此语句创建参数化类型MyClass的实例;该语句显式指定泛型类MyClass的形式类型参数X的类型Integer。请注意,此泛型类的构造函数包含一个形式类型参数T。编译器将为此泛型类的构造函数的形式类型参数T推断类型字符串(因为此构造函数的实际参数是字符串对象)。JavaSE7之前版本的编译器能够推断泛型构造函数的实际类型参数,类似于泛型方法。但是,如果使用菱形(<>),JavaSE7中的编译器可以推断被实例化的泛型类的实际类型参数。考虑以下示例,该示例适用于Java SE 7及更高版本:
MyClass<Integer> myObject = new MyClass<>("");
在本例中,编译器推断泛型类MyClass的形式类型参数X的类型整数。它为泛型类的构造函数的形式类型参数T推断类型字符串。