这就是Java Tutorials定义类型推断的方式:
类型推断是Java编译器查看每个方法的能力 调用和相应的声明来确定类型 使调用适用的参数(或参数)。该 推理算法确定参数的类型,如果 available,分配或返回结果的类型。 最后,推理算法试图找到最具体的类型 适用于所有论点。
下面,它使用所有泛型的例子来解释类型推断。
我的问题是:Java中的类型推断只适用于泛型发挥作用吗?如果没有,我们可以看到一两个例子会有用吗?
答案 0 :(得分:2)
在lambdas中,您不必指定参数类型,也可以返回类型,它们会自动推导出来。例如:
listOfStrings.stream().
map((aString) -> {
//do something
anObject anobject = new anObject();
return anobject;})
.collect(Collectors.toList());
返回列表的类型是List<anObject>
,我没有必要指定aString是String类型,因为它被listOfStrings类型所驱使。
答案 1 :(得分:1)
我的第一个想法是:&#34;不一定&#34 ;;因为编译器分析方法参数以便在重载发生时选择匹配方法(比如理解哪些foo(int)与foo(long)相对于foo(double)应该为某些foo(x)
调用)。
但是,这是关于术语。事实上&#34;一些计算&#34;需要检测正确的重载方法并不意味着&#34; java父亲&#34;认为这些计算可以解释&#34;类型推断&#34;。
恰恰相反:Java语言规范有一整章关于type inference;当你仔细研究它时,它只是&#34;只有&#34;关于泛型类型和lambdas。
所以答案似乎是:当 Java 人们使用该术语时,它只是关于泛型/ lambdas;而不是其他需要分析参数类型的情况。
答案 2 :(得分:1)
在真正的非泛型环境中进行类型推断没有多大意义,因为否则您和编译器已经知道了类型并且不需要编译器干涉任何东西。
然而,我能找到的关闭示例是关于Target Types
。来自文档
采用声明为此
的方法void processStringList(List<String> stringList) {
// process stringList
}
你用它来称呼它
processStringList(Collections.emptyList());
由于Collections.emptyList()
返回List<Object
,如果未指定目标,则会引发错误
List<Object> cannot be converted to List<String>
此处编译器无法干扰List<>
的类型参数。您必须明确提供目标类型,如
processStringList(Collections.<String>emptyList());
然而,JDK 8不再需要了。 Oracle docs Type Inference
Java SE 8中不再需要这个。目标类型的概念已经扩展为包含方法参数,例如方法processStringList的参数。在这种情况下,processStringList需要一个List类型的参数。方法Collections.emptyList返回List的值,因此使用List的目标类型,编译器推断类型参数T的值为String。因此,在Java SE 8中,以下语句编译:
因此,在最后一个示例中,编译器干扰type参数以从List<String>
获取Collections.emptyList()
。