【The Java™ Tutorials】【Generics】6

2018-05-14  本文已影响0人  Ppian

在泛型类型实例化和泛型方法调用的例子中,我们已经接触到了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开始才能这么写。

上一篇下一篇

猜你喜欢

热点阅读