3

以下代码段发出编译器错误。

public List<Long> test()
{
    boolean b=true;
    return b ? Collections.emptyList() : Collections.emptyList();
}

需要不兼容的类型:List<Long>找到:List<Object>

它需要一个泛型类型,例如,

public List<Long> test()
{
    boolean b=true;
    return b ? Collections.<Long>emptyList() : Collections.<Long>emptyList();
}

如果删除此三元运算符,例如,

public List<Long> test()
{
    return Collections.emptyList();
}

或者如果它由类似的if-else构造表示,

public List<Long> test()
{
    boolean b=true;

    if(b)
    {
        return Collections.emptyList();
    }
    else
    {
        return Collections.emptyList();
    }        
}

然后它编译得很好。

为什么第一个案例不编译?在 jdk-7u11 上测试。

4

2 回答 2

4

在三元表达式的情况下,编译器没有机会根据方法的返回类型推断方法Collections.emptyList()的返回类型test。相反,首先它必须解决(三元)表达式的结果类型。并且由于未提及类型,因此它与方法List<Object>的返回类型不兼容test

但是在 中return Collections.emptyList(),它具有可用的(正确的)上下文(即test方法的返回类型),它用于推断返回类型Collections.emptyList()应该是什么。

于 2013-06-03T04:11:23.953 回答
1

简而言之,三元表达式不是从返回类型推断类型参数,而是从它的两个结果表达式推断。由于这种嵌套,必须先确定两种结果类型,才能确定三元的整体结果。

三元表达式的类型取决于其操作数的类型,但其中一个操作数 ( Collections.emptyList()) 具有未确定的类型参数。此时,三元表达式仍然没有类型,所以它不能影响类型参数。有两种类型需要推断——一种是三元表达式的结果,另一种是.emptyList()方法的类型参数。

如您所见,解决方法是显式指定调用的方法类型,通过编码Collections.<Long>emptyList()显式设置类型,然后可用于确定三元表达式的类型,然后根据返回类型检查该类型。

于 2013-06-03T04:42:08.680 回答