[英]Does Java fail to deduce the generic type parameter when using the ternary operator (`?`)?
为什么编译器能够确定赋值的泛型类型参数,而不能确定三元运算符( ?
)?
我有一个问题,关于编译器能够在“直接”赋值的情况下推导出泛型类型参数,但在三元运算符( ?
)的情况下失败。 我的例子使用了Guava的Optional
类来说明我的观点,但我认为底层问题是通用的,不限于Optional
。
Optional
具有通用功能absent()
:
public static <T> Optional<T> absent();
我可以将Optional<T>
分配给Optional<Double>
:
// no compiler error
final Optional<Double> o1 = Optional.absent();
编译器如何实现,在这种情况下T
应该是Double
。 因为在使用三元运算符( ?
)时,我需要特别告诉编译器我们将Integer
作为泛型参数
// Type mismatch: cannot convert from Optional<capture#1-of ? extends Object> to Optional<Integer>
final Optional<Integer> o2 = true
? Optional.of(42)
: Optional.<Integer>absent();
否则我收到以下错误
类型不匹配:无法转换为
Optional<capture#1-of ? extends Object>
Optional<capture#1-of ? extends Object>
为Optional<Integer>
为什么“直接”分配和使用三元运算符之间存在差异? 或者还有其他我想念的东西?
由于类型推断规则,三元表达式似乎不会从返回类型推断出类型参数。 三元表达式的类型取决于其操作数的类型。 但其中一个操作数具有未确定的类型参数( Optional.absent()
)。 此时,三元表达式仍然没有类型,因此它不会影响类型参数。
您还可以查看此错误报告以获取更多信息。 你可以查看JLS 。
条件表达式的类型是将捕获转换(?? 5.1.10)应用于lub(T1,T2)的结果
这是JLS所说的:
如果方法结果发生在它将被赋值转换为类型S的上下文中,那么让R成为方法的声明结果类型,并让R'= R [T1 = B(T1)... Tn = B(Tn)]其中B(Ti)是上一节中Ti的推断类型,如果没有推断出类型,则为Ti。
问题是,ternery操作员的结果被分配给o2。 编译器无法在多个操作中推断出类型。
基本上我认为你写的简短形式:
Optional<?> tmp = true ? Optional.of(42): Optional.absent();
final Optional<Integer> o2 = tmp;
第二行的转换是问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.