什么是Java?:运算符,它的作用是什么?


161

我已经使用Java几年了,但是直到最近我还没有遇到过这种构造:

int count = isHere ? getHereCount(index) : getAwayCount(index);

这可能是一个非常简单的问题,但是有人可以解释吗?我该如何阅读?我很确定我知道它是如何工作的。

  • 如果isHere为真,getHereCount()则称为
  • 如果isHere为假,getAwayCount()则调用。

正确?这个结构叫做什么?


2
有关此问题的C ++版本,请参阅stackoverflow.com/questions/795286/what-does-do-in-c(实际上是昨天才提出的)。
Michael Myers

2
请记住,C / C ++ / Java世界在认为丑陋和令人困惑并会像瘟疫一样避免它的人们之间平均分配,而那些认为您不能真正声称知道C,C ++或Java的人们不能停下来思考就无法识别和使用它。
Paul Tomblin,2009年

3
在Java的一般形式中,超出最清楚和最简单的情况使用它通常是不好的形式。如果您发现自己嵌套它们,那您就出路了。另一方面,在C语言文化中,对快速,聪明的代码的重视程度超过其清晰度,这被认为是可以接受的。
Yishai

17
answer_to_question =(recognize_operator)吗?(social_acceptance):(condescending_finger_wag)

您可以参考资源以获取更多信息。
湿婆

Answers:


189

是的,它是

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

它称为条件运算符。许多人(错误地)将其称为三元运算符,因为它是Java,C,C ++以及其他许多语言中唯一的三元运算符。但是理论上可以有另一个三元运算符,而只能有一个条件运算符

官方名称在Java语言规范中给出

§15.25条件运算符 :

条件运算符? :使用一个表达式的布尔值来确定应评估另外两个表达式中的哪一个。

请注意,两个分支都必须导致带有返回值的方法:

第二个或第三个操作数表达式是void方法的调用是编译时错误。

实际上,根据表达式语句的语法(第14.8节),不允许在可能出现调用void方法的任何上下文中出现条件表达式。

因此,如果doSomething()doSomethingElse()是无效方法,则无法压缩此方法:

if (someBool)
    doSomething();
else
    doSomethingElse();

到这个:

someBool ? doSomething() : doSomethingElse();

简单的话:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 

我不明白最底层的是什么错误。我相信你和所有人。在我看来,它与原始版本相同。是因为它们只是调用了另一个可能会或可能不会返回值并允许下一个代码集运行的函数?
约翰尼,2009年

8
我假设doSomething()和doSomethingElse()是无效方法。规范的最后一点是,三元运算符必须返回一个值,因此所有操作数都不可以是void方法。
迈克尔·迈尔斯

它说的不止于此。它说在出现void方法的地方不允许使用条件运算符。因此,例如,以下语句:VALID:字符串x =(false)?“ X”:“ Y”; 无效:(假)?“ X”:“ Y”;
kenj0418

4
称其为“三元经营者”并不是错误的,就像在2016年称奥巴马为“总统”并不是错误的,即使将来可能还会有其他总统。
达伍德·伊本·卡里姆

2
@DawoodibnKareem我认为Michael故意包含the在的斜体中the ternary operator就是他的意思是错误的,而不是ternary operator错误的。三元运算符暗示,迈克尔说,这是唯一的一个,这反过来又可能导致一个假设不能有任何其他的三元运营商,这是迈克尔说是错误的,而且我同意,这是一个错误的假设。
Ghoti和Chips

32

其他人已经在合理范围内回答了这个问题,但通常使用“三元运算符”的名称。

作为我自己的学徒,我想明确指出运算符的名称是条件运算符或“条件运算符?:”。它是一个三元运算符(因为它具有三个操作数),并且碰巧是目前Java中唯一的三元运算符。

但是,该规范非常清楚,它的名称是条件运算符或“条件运算符?:”,这是绝对明确的。我认为用该名称称呼更清楚,因为它在某种程度上指示了运算符的行为(评估条件),而不是仅仅表示它具有多少个操作数。


3
这个答案在技术上是正确的。但是,由于只有一个三元运算符,您经常会看到它被称为三元运算符。即使此名称未传达操作员的完整含义,但该名称已被保留。如果您提到“三元运算符”的名称,那么程序员就会知道您在说什么。您提到的规范也将此运算符称为“三元条件”,它似乎更有用。 java.sun.com/docs/books/jls/third_edition/html/…–
加里

17
我只是认为以定义的名称来调用某些东西是值得的。特别是,如果Java获得了另一个三元运算符,那么使用“条件运算符”一词的人仍将是正确且明确的-与那些只说“三元运算符”的人不同。是的,短语“三元运算符”已被卡住-我的回答是“解粘”工作的一部分,就像我试图纠正“对象通过引用传递”的说法一样。
乔恩·斯凯特

1
我可以从Oracle引导您到此页面,它涉及三个“条件运算符”,但仅一个“三元运算符”吗?如果您想弄清楚您的意思是哪个运算符,最好使用大多数人使用的名称。(是的,我知道我正在参加聚会,就像主持人在洗最后一道菜一样)。
达伍德·伊本·卡里姆

@DavidWallace:使用“条件运算符?:”更好,IMO-将进行编辑以阐明这一点。但是我确实认为有必要说服人们使用操作符的实际名称,而不是专注于与其行为无关的一个方面(操作符有多少个操作数)。(对于教程而言,其精确性要比规范差一些,这称为&&条件和运算符,以及||条件或运算符,而只使用“条件运算符” ?:
Jon Skeet

我不知道。如果有人对我说“条件运算符”,我将不确定它们的含义。我来自哪里(与您相反的世界),人们只是不这么称呼它。如果他们说“三元运算符”或“ hook运算符”,那么我理解。我欣赏您的雄心壮志,想改变人们的交谈方式。如果有人能做到,那就是你。但是我既没有抱太大希望,也没有看到很多意义。
达伍德·伊本·卡里姆

17

根据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,否则会发生编译时错误。


5
int count = isHere ? getHereCount(index) : getAwayCount(index);

表示:

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

5

确切地说,并不完全正确:

  1. 如果isHere为true,则返回 getHereCount()的结果
  2. 否则返回 getAwayCount()的结果

那“归来”非常重要。这意味着方法必须返回一个值,并且必须在某个位置分配该值。

此外,它在语法上也不等同于if-else版本。例如:

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

如果使用if-else编码,将始终导致更多字节码。


我相信javac可以自由生成相同的字节码。尽管您是正确的,但在某些不明显的极端情况下它们并不等效。
Tom Hawtin-大头钉

当然是。对我来说,条件运算符的真正优点是我给出的示例。替代方法是://喘着粗气!字符串temp = str1; 如果(检查)temp + = str2; 否则temp + = str3; temp + = str4; 返回温度 或手动编码StringBuilder追加操作。第一个遭受严重的效率问题,而第二个则过于冗长,是一项艰巨的努力,没有太大的收获。
RichN

4

三元,有条件的;番茄,tomatoh。真正有用的是变量初始化。如果(像我一样)喜欢在定义变量的地方初始化变量,则条件三元运算符(因为它们都是两者)允许您在变量值存在条件的情况下执行此操作。在最终领域中尤其值得注意,但在其他领域也很有用。

例如:

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

如果没有该运算符(无论使用什么名称),您都必须使该字段为非最终值,或者编写一个函数来对其进行初始化。实际上,这是不对的-至少在Java中,仍然可以使用if / else对其进行初始化。但是我发现这种清洁剂。



3

这种构造在计算机科学和编程技术中称为三元运算符
维基百科提出了如下解释:

在计算机科学中,三元运算符(有时错误地称为三元运算符)是一个带有三个参数的运算符。参数和结果可以是不同的类型。许多使用类似于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);
}

而已!
希望这对某人有帮助!
干杯!



2

三元运算符(?:)

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.

1

您可能对针对一些与条件运算符相似的新运算符的提案感兴趣。空安全运算符将启用以下代码:

String s = mayBeNull?.toString() ?: "null";

自动拆箱的地方特别方便。

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

它已根据JDK 7的“项目硬币” 进行了进一步选择


该运算符不是我在Project Coin中的最爱之一。有用的功能有限,阅读起来不直观,而且每次都变得很丑陋。也许它会在我身上成长。
迈克尔·迈尔斯

实际上,我也不是超级粉丝。这是Neal Gafter的建议,他倾向于与普通的Java程序员看到不同的东西,而Java程序员却与普通人不同。我可能希望对null有所帮助的唯一地方是在foreach循环中,测试iterable是否为null,然后自动拆箱。
erickson

IIRC <Neal没有提出。他只是将其用作编写建议的简单示例。有关项目投币邮件列表存档的更多详细信息。
Tom Hawtin-大头钉

我刚刚阅读了该提案的简介,您是对的。这是Joda的Stephen Colebourne和“没有Java 7”的声望。
erickson

1

实际上,可能需要3个以上的参数。例如,如果我们要检查数字是正数,负数还是零,我们可以这样做:

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

这比使用if,else if,else更好。


0

它是条件运算符,它不只是一种简单的if语句编写方式。

由于它是一个返回值的表达式,因此可以用作其他表达式的一部分。


0

是的,你是对的。?:通常称为“三元条件运算符”,通常简称为“三元运算符”。它是标准if / else有条件的简写版本。

三元条件运算符


0

我碰巧真的很喜欢这个运算符,但是应该考虑读者。

您始终必须在代码紧凑性和阅读时间之间取得平衡,因为它存在一些非常严重的缺陷。

首先,有原始阿斯克案。他只是花了一个小时发布有关它的内容,并阅读了回复。作者每写一次要花多长时间?:一生中是否/曾经如此。不到一个小时就可以确定。

其次,在类似C的语言中,您习惯于简单地知道条件是该行的第一件事。当我使用Ruby时,我注意到了这一点,并且遇到了类似以下行:

callMethodWhatever(Long + Expression + with + syntax) if conditional

如果我是Ruby的长期用户,那么这行可能不会有问题,但是来自C,当您看到“ callMethodWhatever”是该行的第一件事时,您希望它会被执行。?:不太神秘,但是仍然足以使读者失望。

但是,优点是当您可以在三行中的1行中写一条三行if语句时,您的肚子会感觉很酷。不能否认:)但是,老实说,仅仅因为它的稀有性,不一定90%的人就可以阅读。

当它确实是一个基于布尔值和值的赋值时,我对此没有任何问题,但是很容易被滥用。


0

条件表达式的样式完全不同,语句中没有明确的条件。

语法为:boolean-expression?expression1:expression2;

该条件表达式的结果是

如果布尔表达式为true,则为expression1;否则为false。

否则结果为expression2。

假设您要分配更大数量的变量num1和num2到max。您可以简单地使用条件表达式编写一条语句:max =(num1> num2)?num1:num2;

注意:符号?和:一起出现在条件表达式中。它们形成条件运算符,也称为三元运算符,因为它使用三个操作数。它是Java中唯一的三元运算符。

引用自:Y. Daniel Liang第126-127页Java编程简介第10版

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.