我在编写一些Java代码时遇到了编译失败,我将其简化为以下测试用例:
import java.util.Collections;
import java.util.List;
public class TernaryFailure {
public static List<String> thisWorks() {
return Collections.emptyList();
}
public static List<String> thisFailsToCompile() {
return true ? Collections.emptyList() : Collections.emptyList();
}
}
上面的代码无法javac
使用JDK 1.7.0_45 进行编译:
$ javac TernaryFailure.java TernaryFailure.java:10: error: incompatible types return true ? Collections.emptyList() : Collections.emptyList(); ^ required: List<String> found: List<Object> 1 error
但是,使用JDK 1.8.0_05编译时不会出现任何错误。
这是Java 7实现中的错误吗?还是对Java 8中的Java语言规范进行了增强以开始允许这样做-如果是这样,有什么变化?
JLS SE
8在(§15.2)中说:
当某些表达式出现在某些上下文中时,它们被视为多表达式。以下形式的表达式可以是多边形表达式:
带括号的表达式(第15.8.5节)
类实例创建表达式(第15.9节)
方法调用表达式(第15.12节)
方法引用表达式(第15.13节)
条件表达式(第15.25节)
Lambda表达式(§15.27)
因此,从规范的这一部分可以清楚地看出,条件表达式(即三元运算符)可以视为多表达式。但是,并非所有条件表达式都可以视为多表达式,只能引用根据(§15.25)的条件表达式。(§15.25.3)阐明了可以将参考条件表达式视为多表达式的条件:
如果引用条件表达式出现在分配上下文或调用上下文中(第5.2节至第5.3节),则它是一个多边形表达式。否则,它是一个独立的表达式。
当多引用条件表达式出现在目标类型为T的特定种类的上下文中时,其第二和第三操作数表达式类似地出现在目标类型为T的相同种类的上下文中。
多边形引用条件表达式的类型与其目标类型相同。
检查示例中条件表达式是否出现在赋值上下文中,因为根据(§14.17):
当带有表达式的return语句出现在方法声明中时,该表达式必须可分配给该方法的声明返回类型(第5.2节),否则会发生编译时错误。
那么到最后,这意味着什么?这意味着,当条件表达式为多边形表达式时,目标类型将“推入”到每个操作数中。这样,编译器可以将条件的每个部分归于目标。您的目标是List<String>
。如果我们检查emptyList()方法的定义,我们将:
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
因此,使用target List<String>
,编译器可以推断出T == String且代码已被接受。
问题内容: 为什么会产生错误,应如何写? 错误是“找不到<接受提供的参数的重载” 问题答案: 您的三元运算符在那里不工作的 原因 是由于各种中缀运算符的优先级。您可以在此处查看运算符优先级列表。如果您看一下,会发现底部的运算符通常是放置在较大代码段之间的运算符。优先级越高,它将越紧紧抓住左侧(或右侧)的表达式。因此,您通常希望您的运算符具有非常低的关联性,因此在类似以下的表达式中: 该会抢在它两侧
问题内容: 此类在Java 7中可以编译,但在Java 8中不能编译: 编译错误: 错误:(9,29)java:类Foo中的方法foo无法应用于给定类型;必需:java.lang.Class找到:true吗?str […]类 原因:推断的类型不符合相等的约束推断的:java.lang.StringBuilder相等约束:java.lang.StringBuilder,java.lang.Strin
请考虑此类: null
问题内容: 为什么编译正常但有错误?(更确切地说, “类型不匹配:无法从List 转换为List ” ) 我本以为两个函数都可以编译为相同的字节码,所以一个聪明的编译器应该为… 推断正确的类型。 问题答案: 我可以在Java 8中正常编译。 Java的早期版本可能需要更多帮助 应该管用。 编辑 这是由于Java 8类型推断的改进,如此处所述 http://openjdk.java.net/jeps
条件(三元)运算符是 JavaScript 仅有的使用三个操作数的运算符。一个条件后面会跟一个问号(?),如果条件为 truthy ,则问号后面的表达式A将会执行;表达式A后面跟着一个冒号(:),如果条件为 falsy ,则冒号后面的表达式B将会执行。本运算符经常作为 if 语句的简捷形式来使用。(MDN) 三元运算符,也称条件运算符、三目运算符。 三元运算符可以代替简单的 if 语句。 1. 语
据我所知,PowerShell似乎没有一个针对所谓三元运算符的内置表达式。 例如,在支持三元运算符的C语言中,我可以编写如下内容: 如果PowerShell中并不存在这种情况,那么实现相同结果的最佳方法(即易于阅读和维护)是什么呢?