
要回答您的问题“意思是,是否存在一种已知的打破类型推断的模式?”
简短地说:当然,有一种模式,而且对于Java编程语言的整个行为都有一个巨大的规范。
但是有关类型推断和方法调用类型的章节确实详尽且难以理解。这可以通过以下事实得到最好的说明:在发生意外行为的情况下,经常会根据规范对预期行为进行大量讨论。
但是对于程序员来说,有些地方是可以解释和记住的。
有两种方法可以通过传递给组成表达式的方法或部分的参数或表达式的 目标类型
(即调用参数的预期类型)来推断类型参数。如果有return语句,则分配该值或方法的返回类型。
目标类型可以通过嵌套方法调用传播,例如
TargetType x=foo(bar());
或有条件的
TargetType x=condition? foo(): foo();
但 不是像 这样的链式调用
TargetType x=foo().foo();
现在来看您的示例:
ImmutableMap<String, Integer> map1 = Stream.of("1", "2", "3").collect( expression );在这里,
Stream.of(…)和
.collect(…)是 链接在一起的
,因此不能使用目标类型来确定
of调用的流类型,但是提供给该方法的参数足以推断类型
Stream<String>。该
collect方法提供分配给结果的结果
map1,因此流类型
Stream<String>
和 目标类型
ImmutableMap<String, Integer>都是已知的,并且可用于 表达式 的类型推断。在表达式上:
Testcase.toImmutableMap(keyMapper, valueMapper).build()
这是一个链式调用,因此目标类型是已知的,build()
但不是toImmutableMap
。但是,to的参数toImmutableMap
是具有已知确切类型的局部变量,因此类型推断可以使用它们来推断的结果类型,toImmutableMap
并检查其是否符合预期。.build()
Testcase.toImmutableMap(i -> i, Integer::valueOf).build()
这又是一个链式调用,但是现在参数i - > i
具有不完整的类型,并且缺少目标类型。在i -> i
不了解目标类型的情况下猜测类型的尝试失败。Testcase.toImmutableMap2(i -> i, Integer::valueOf)
这 不是 链式调用,因此目标类型可用于该toImmutableMap2
调用(就该collect
调用而言,它是一个嵌套调用)。因此,的目标类型toImmutableMap2
允许推断参数的目标类型,从而推断i -> i
lambda表达式。使用正确的目标类型,可以推断出正确的功能签名。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)