我有以下代码,
class Foo<K> {
public <T> T createK() {
return null;
}
public void foo() throws ClassNotFoundException {
K k = (1==1)?null:createK();
}
}
然而,它没有编译。它使用条件运算符导致了以下编译错误(Oracle Java 7):
类型不匹配:无法从Object转换为K
当我按如下方式重写foo()
方法时,
public void foo() throws ClassNotFoundException {
K k = null;
if (1==1)
k = null;
else
k = createK();
}
然后编译好。这是怎么造成的,我该如何解决?
答案 0 :(得分:6)
尽管条件运算符与if-else
条件运算符不完全相同,但这是一个不同的问题。
This is a known bug,它不能按预期工作。
解决方案是提供显式类型参数:
K k1 = (1==1) ? null : this.<K>createK();
...这可行,但是编译器警告 - 死代码(当然,由于1 == 1
部分)。注意,我们需要如何显式使用this
来使用显式类型参数调用该方法。简单地执行<K>createK()
将无效。
使用方法调用添加显式类型参数 - this.<K>createK();
强制将类型T
推断为K
,否则将其推断为Object
。
但是,我怀疑你的疑问与类型推断有关。这个问题就出现了,这只是巧合。尽管如此,为了了解条件运算符在不同情况下的工作方式,以及结果的类型,您可以安排访问JLS §15.25 - Conditional Operator
答案 1 :(得分:4)
不,三元(即? :
)是来自if ... then ... else
的非常不同的野兽。
三元组是运算符,两个选项必须是 表达式,评估为相同类型 。
if ... then ... else
是一种方便的编程结构;中间的位是语句而不是表达式。
实际上,整个三元构造是一个表达式,而if ... then ... else
本身就是一个语句。 (您可以为三元组分配值;例如foo = ... ? ... : ...
但foo = if ... then ... else
无意义,因此在语法上无效。)
答案 2 :(得分:1)
您的代码无法编译,因为条件表达式的两边类型必须匹配。对if
语句没有这样的要求 - 实际上,不要求两个部分以任何方式相互关联,更不用说分配相同的变量。 / p>
添加强制转换可修复条件(demo on ideone):
K k = (1==1)?null:(K)createK();
答案 3 :(得分:1)
那些运营商是不同的。
1)如果if ... then ... else
没有行动限制
2)三元运算符。使用双方必须具有相同的类型。
您可以使用强制转换修复所有内容:
K k = (1 == 1) ? null : (K)(createK());
答案 4 :(得分:-1)
使用条件? valueA:valueB运算符仅在存在左值时才有意义,
左值=条件? valueA:valueB
此运算符的确切meannig可以转换为if else语句:
int y,z;
int x =(y == 0)? y + 1:z + 3
这最终与:
相同if(y==0)
{
x=y+1;
}else
{
x = z+3;
}