我已经使用 Java 几年了,但直到最近我还没有遇到过这个结构:
int count = isHere ? getHereCount(index) : getAwayCount(index);
这可能是一个非常简单的问题,但是有人可以解释一下吗?我该如何阅读?我很确定我知道它是如何工作的。
- 如果
isHere
为真,getHereCount()
则调用, - if
isHere
is falsegetAwayCount()
被调用。
正确的?这个结构叫什么?
我已经使用 Java 几年了,但直到最近我还没有遇到过这个结构:
int count = isHere ? getHereCount(index) : getAwayCount(index);
这可能是一个非常简单的问题,但是有人可以解释一下吗?我该如何阅读?我很确定我知道它是如何工作的。
isHere
为真,getHereCount()
则调用,isHere
is falsegetAwayCount()
被调用。正确的?这个结构叫什么?
是的,它是一种简写形式
int count;
if (isHere)
count = getHereCount(index);
else
count = getAwayCount(index);
它被称为条件运算符。许多人(错误地)称它为三元运算符,因为它是 Java、C、C++ 和可能许多其他语言中唯一的三元(三参数)运算符。但理论上可以有另一个三元运算符,而只能有一个条件运算符。
Java 语言规范中给出了正式名称:
§15.25 条件运算符?:
条件运算符
? :
使用一个表达式的布尔值来决定应该计算其他两个表达式中的哪一个。
请注意,两个分支都必须指向具有返回值的方法:
第二个或第三个操作数表达式调用 void 方法是编译时错误。
事实上,根据表达式语句的语法(第 14.8 节),条件表达式不允许出现在可能出现 void 方法调用的任何上下文中。
因此,如果doSomething()
和doSomethingElse()
是 void 方法,则不能压缩:
if (someBool)
doSomething();
else
doSomethingElse();
进入这个:
someBool ? doSomething() : doSomethingElse();
简单的话:
booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse
其他人已经在合理程度上回答了这个问题,但通常使用“三元运算符”的名称。
作为学究,我想明确一点,运算符的名称是条件运算符或“条件运算符?:”。它是一个三元运算符(因为它有三个操作数),它恰好是目前 Java 中唯一的三元运算符。
但是,规范非常清楚,它的名称是条件运算符或“条件运算符?:”,这是绝对明确的。我认为用这个名字来称呼它更清楚,因为它在某种程度上表明了运算符的行为(评估条件),而不仅仅是它有多少个操作数。
根据Sun Java Specification,它被称为条件运算符。请参见第 15.25 节。你对它的作用是正确的。
条件运算符 ? : 使用一个表达式的布尔值来决定应该评估其他两个表达式中的哪一个。
条件运算符在语法上是右关联的(它从右到左分组),因此 a?b:c?d:e?f:g 与 a?b:(c?d:(e?f :G))。
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression
条件运算符具有三个操作数表达式;? 出现在第一个和第二个表达式之间,并且 : 出现在第二个和第三个表达式之间。
第一个表达式必须是 boolean 或 Boolean 类型,否则会发生编译时错误。
int count = isHere ? getHereCount(index) : getAwayCount(index);
方法 :
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
不完全正确,准确地说:
那个“回归”很重要。这意味着方法必须返回一个值,并且该值必须分配到某个地方。
此外,它在语法上并不完全等同于 if-else 版本。例如:
String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;
如果用 if-else 编码总是会产生更多的字节码。
三元,有条件的;番茄,番茄。它真正有价值的是变量初始化。如果(像我一样)您喜欢在定义变量的地方初始化变量,那么条件三元运算符(因为两者都是)允许您在其值存在条件的情况下这样做。在 final 领域尤其显着,但在其他领域也很有用。
例如:
public class Foo {
final double value;
public Foo(boolean positive, double value) {
this.value = positive ? value : -value;
}
}
如果没有该运算符 - 无论名称如何 - 您都必须使该字段成为非最终字段或编写一个函数来初始化它。实际上,这是不对的——它仍然可以使用 if/else 来初始化,至少在 Java 中是这样。但我发现这个更清洁。
您可能对一些类似于条件运算符的新运算符的提议感兴趣。空安全运算符将启用如下代码:
String s = mayBeNull?.toString() ?: "null";
在进行自动拆箱时会特别方便。
Integer ival = ...; // may be null
int i = ival ?: -1; // no NPE from unboxing
它已在 JDK 7 的“Project Coin”中被选中以供进一步考虑。
这种结构在计算机科学和编程技术中称为三元运算符。维基百科建议以下解释
:
在计算机科学中,三元运算符(有时被错误地称为三元运算符)是一个接受三个参数的运算符。参数和结果可以是不同的类型。许多使用类 C 语法的编程语言都有一个三元运算符 ?: ,它定义了一个条件表达式。
不仅在 Java 中,这种语法在 PHP、Objective-C 中也可用。
在下面的链接中,它给出了以下解释,这很好理解:
三元运算符是在 3 个输入上进行的某种运算。它是 if-else 语句的快捷方式,也称为条件运算符。
在 Perl/PHP 中,它的工作方式如下:
boolean_condition ? true_value : false_value
在 C/C++ 中,它的工作方式如下:
logical expression ? action for true : action for false
这对于一些不太复杂的逻辑条件可能是可读的,否则最好将If-Else 块与条件逻辑的预期组合一起使用。
我们可以为一个代码语句行使用此三元运算符简化If-Else 块。
例如:
if ( car.isStarted() ) {
car.goForward();
} else {
car.startTheEngine();
}
可能等于以下内容:
( car.isStarted() ) ? car.goForward() : car.startTheEngine();
因此,如果我们参考您的陈述:
int count = isHere ? getHereCount(index) : getAwayCount(index);
它实际上是以下If-Else 块的 100% 等效项:
int count;
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
就是这样!
希望这对某人有帮助!
干杯!
它的三元运算符(?:)
The ternary operator is an operator that takes three arguments. The first
argument is a comparison argument, the second is the result upon a true
comparison, and the third is the result upon a false comparison.
实际上它可能需要 3 个以上的参数。例如,如果我们想检查一个数字是正数、负数还是零,我们可以这样做:
String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";
这比使用 if、else if、else 更好。
是的,你是对的。?: 通常称为“三元条件运算符”,通常简称为“三元运算符”。它是标准 if/else 条件的简写版本。
它是条件运算符,它不仅仅是一种编写 if 语句的简洁方式。
由于它是一个返回值的表达式,因此它可以用作其他表达式的一部分。
我碰巧很喜欢这个运算符,但应该考虑到读者。
你总是必须在代码紧凑性和阅读时间之间取得平衡,因为它有一些非常严重的缺陷。
首先是原始提问者的案例。他只花了一个小时发布关于它并阅读回复。作者要花多长时间来写每一个?:作为一个如果/那么在他的整个生命过程中。肯定不是一个小时。
其次,在类 C 语言中,您习惯于简单地知道条件是行中的第一件事。我在使用 Ruby 时注意到了这一点,并遇到了以下问题:
callMethodWhatever(Long + Expression + with + syntax) if conditional
如果我是一个长期使用 Ruby 的用户,我可能不会对这一行有任何问题,但是来自 C 语言,当您看到“callMethodWhatever”作为该行中的第一件事时,您希望它会被执行。?: 不那么神秘,但仍然很不寻常,足以让读者望而却步。
然而,当您可以在其中 1 行的空间中编写 3 行 if 语句时,优势是在您的肚子里有一种非常酷的感觉。不能否认 :) 但老实说,仅仅因为它的稀有性,90% 的人不一定更容易阅读。
当它确实是基于布尔值和值的分配时,我没有问题,但它很容易被滥用。
条件表达式的风格完全不同,语句中没有明确的 if。
语法是:布尔表达式?表达式1:表达式2;
这个条件表达式的结果是
如果布尔表达式为真,则表达式 1;
否则结果为表达式 2。
假设您要将较大数量的变量 num1 和 num2 分配给 max。您可以使用条件表达式简单地编写一个语句: max = (num1 > num2) ? 数字1:数字2;
注意:符号 ? 和 : 一起出现在条件表达式中。它们构成条件运算符,也称为三元运算符,因为它使用三个操作数。它是Java中唯一的三元运算符。
引自:Y. Daniel Liang 第 10 版 Java 编程简介,第 126 - 127 页