1

我有以下代码,

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();
}

然后它编译得很好。这是如何引起的,我该如何解决?

4

5 回答 5

6

虽然条件运算符与条件运算符不完全相同if-else,但这是一个不同的问题。

这是一个已知的错误,带有条件运算符的泛型类型参数的类型推断不能按预期工作。

解决方案是提供显式类型参数:

K k1 = (1==1) ? null : this.<K>createK(); 

...这会起作用,但是有编译器警告 -死代码(当然,由于1 == 1部分原因)。请注意,我们需要如何显式使用this来调用具有显式类型参数的方法。简单地做是<K>createK()行不通的。

使用方法调用添加显式类型参数 -this.<K>createK();强制类型T推断为K,否则推断为Object


但是,我怀疑您的疑问确实与类型推断有关。问题的出现只是一个巧合。尽管如此,要了解条件运算符在不同情况下的工作方式及其结果的类型,您可以安排访问JLS §15.25 - Conditional Operator

于 2013-10-10T20:07:39.803 回答
4

不,三元(即? :if ... then ... else.

三元是一个运算符,两个备选方案必须是计算为相同类型的表达式

if ... then ... else是一种方便的编程结构;中间的位是语句而不是表达式。

事实上,整个三元结构是一个表达式,而 theif ... then ... else本身就是一个语句。(您可以为三元分配一个值;例如foo = ... ? ... : ...,但是foo = if ... then ... else没有意义,因此在语法上无效。)

于 2013-10-10T20:02:15.130 回答
1

这些运营商是不同的。

1) 在if ... then ... else没有行动限制的情况下

2) 三元运算符。使用双方必须具有相同的类型。

您可以使用 cast 修复所有问题:

K k = (1 == 1) ? null : (K)(createK());
于 2013-10-10T20:06:27.877 回答
1

您的代码无法编译,因为条件表达式两边的类型必须匹配。if 语句没有这样的要求——事实上,没有要求这两个部分以任何方式相互关联,更不用说分配相同的变量了。

添加演员表可以修复您的条件(ideone 上的演示):

K k = (1==1)?null:(K)createK();
于 2013-10-10T20:04:50.500 回答
-1

使用条件 ? valueA : valueB 运算符只有在存在 Lvalue 时才有意义,

左值 = 条件?值A:值B

该运算符的确切含义可以转换为 if else 语句:

int y,z;

整数 x= (y==0) ?y+1 : z+3

这最终与以下内容相同:

if(y==0)
{
    x=y+1;
}else
{
    x = z+3;
}
于 2013-10-10T20:08:47.890 回答