【问题标题】:Java if ternary operator and Collections.emptyList()Java if 三元运算符和 Collections.emptyList()
【发布时间】:2011-10-12 10:54:26
【问题描述】:

您能否解释一下为什么第一个返回类型无法编译代码? 消息是:Type mismatch: cannot convert from List<capture#1-of ? extends Object> to List<String>

是否在第二种情况下插入了显式转换?

public class GenericsTest {

        private String getString() {
            return null;
        }

        public List<String> method() {
            String someVariable = getString();
            //first return type
            //return someVariable == null ? Collections.emptyList() : Collections.singletonList(someVariable);
            //second return type
            if (someVariable == null) {
                return Collections.emptyList();
            } else {
                return Collections.singletonList(someVariable);
            }
        }
    }

【问题讨论】:

    标签: java generics casting


    【解决方案1】:

    因为类型推断规则。我不知道为什么完全正确(你应该检查 JSL,the ternary operator section),但看起来三元表达式没有从返回类型推断类型参数。

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

    使用Collections.&lt;String&gt;emptyList() 显式设置类型

    【讨论】:

    • 您能详细解释一下吗?问题不在于如何解决它。
    • 我已经回答的差不多了。我现在懒得深入研究 JLS,但我可以验证规则不要求(实际上不允许)让本次使用三元运算符编译。信息都在那里,所以如果有正确的规则,这肯定是可能的。
    【解决方案2】:

    表达式flag ? trueCase : falseCase 的类型是这两种情况中最常见的类型。

    在这种情况下,Collections.emptyList()Collections.singletonList(someVariable) 最常见的类型是 List&lt;? extends Object&gt;,因为它无法“看到未来”Collections.emptyList() 应该在表达式中返回 List&lt;String&gt;


    当你这样做时:

    return Collections.emptyList();
    

    编译器可以很聪明,通过返回类型检测类型并检查正确性(推断)。

    【讨论】:

      【解决方案3】:

      因为Collections.emptyList() 不会返回List&lt;String&gt;。您将该方法的结果显式设置为List&lt;String&gt;,这意味着您必须返回一个这样的列表。

      例如

      return Collection<String>.emptyList(); 
      

      return new ArrayList<String>();
      

      可以正常工作。

      【讨论】:

      • 不是真的:Collections.singletonList("string") 确实返回List&lt;String&gt;Collections.emptyList()可以返回List&lt;String&gt;,具体取决于上下文(如示例代码中的第二个return 所示)。
      • -1:事实上不正确。 Collections.emptyList() 和 Collections.singletonList("string") 实际上返回 List。问题在于泛型的类型推断。
      • 我很高兴收回反对票。我当然没有看到你的更正。
      • 请注意:Tobias 从一开始就写了List&lt;String&gt;,但由于它没有被标记为代码,&lt;String&gt; 部分被解释为 HTML 标记,因此被默默删除。它仍然不是 100% 正确,但没有声称 Collections.emptyList() 不会返回 List 那样糟糕。
      • 感谢您的指正,下次我将使用特殊字符来标记代码。
      猜你喜欢
      • 1970-01-01
      • 2013-12-04
      • 2021-03-17
      • 2010-12-12
      • 2021-01-03
      • 2012-08-08
      • 1970-01-01
      • 2014-02-08
      相关资源
      最近更新 更多