在泛型类型实例化和泛型方法调用的例子中,我们已经接触到了Type Inference。本章就来详细介绍Type Inference。
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.
Note: It is important to note that the inference algorithm uses only invocation arguments, target types, and possibly an obvious expected return type to infer types. The inference algorithm does not use results from later in the program.
我们先来看下面这段代码:
static <T> T pick(T a1, T a2) { return a2; }
Serializable s = pick("d", new ArrayList<String>());
从target types推断:T应该是Serializable(String和ArrayList<String>都实现了Serializable接口)。
如果没有将返回值赋给s呢?我猜测编译器推断出的T是String和ArrayList<String>的共同祖先Object,因为编译器给出的提示和Object的方法一致:
Type Inference and Generic Methods
public class BoxDemo {
public static <U> void addBox(U u,
java.util.List<Box<U>> boxes) {
Box<U> box = new Box<>();
box.set(u);
boxes.add(box);
}
}
BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
可以简写为:
BoxDemo.addBox(Integer.valueOf(10), listOfIntegerBoxes);
Type Inference and Instantiation of Generic Classes
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
可以简写为:
Map<String, List<String>> myMap = new HashMap<>();
注意不要漏掉<>。
Type Inference and Generic Constructors of Generic and Non-Generic Classes
class MyClass<X> {
<T> MyClass(T t) {
// ...
}
}
MyClass<Integer> myObject = new MyClass<Integer>("");
可以简写为:
MyClass<Integer> myObject = new MyClass<>("");
Target Types
List<String> listOne = Collections.emptyList();
编译器能够推断出Collections.emptyList()需要返回List<String>。
如果上面这种写法编译器能够推断出类型,那么下面这种写法应该也能够推断出来吧?
void processStringList(List<String> stringList) {
// process stringList
}
processStringList(Collections.emptyList());
可惜,这在Java 7及之前的版本是不支持的,从Java 8开始才能这么写。