【问题标题】:Why can't Ternary operator be used without assignment (variable on the left)?为什么不能在没有赋值的情况下使用三元运算符(左侧的变量)?
【发布时间】:2019-04-26 06:31:56
【问题描述】:

我已对此进行了搜索,并且有一些关于同一问题的问题,但这些问题的答案似乎都无法解决我的问题。

我查阅了规范并设法找到以下几点:

  • 第一个三元表达式必须是布尔类型

  • 第二个和第三个表达式不能调用 void 方法。

如果我编写以下代码,则给出上述信息

String res;
System.out.println(res="walter");

它将 walter 打印到控制台,这意味着表达式返回了一些东西,因此它不是无效的。但是现在如果尝试写这个

String stuff = "TV";
String res=null;
stuff.equals ("TV") ? res= "Walter" :  res = "White" ;

此代码无法编译 赋值的左边必须是变量

即使满足上述两个条件(据我所知)。为什么代码无法编译以及为什么它需要左侧的变量?

如果我这样做

res = stuff.equals("TV")?res="WALTER":res="WHITE";

代码编译失败

对于参数类型 java.lang.String,java.lang.String,运算符

但以下编译正常

res = stuff.equals("TV")?res="WALTER":"WHITE";

PS

  • 为什么三元运算符左边一定要有变量,方法返回值可以丢弃,为什么在三元的情况下不能这样做。
  • 为什么 Java 不允许它,如果允许它会导致什么问题或不一致

【问题讨论】:

  • 因为它是一个表达式,而不是一个 StatementExpression。
  • 不知道你为什么要这样完成作业,你应该可以这样做:res = stuff.equals("TV") ? "Walter" : "White" ; 这有点干净,让你不必把res = 多次
  • 部分答案:第一个语法错误是由于运算符优先规则造成的。 stuff.equals ("TV") ? res= "Walter" : res = "White" 被解析为 (stuff.equals ("TV") ? res= "Walter" : res) = "White"。尝试改用stuff.equals ("TV") ? res= "Walter" : (res = "White"),但即便如此,由于安迪给出的原因,它也无法编译。

标签: java ternary-operator


【解决方案1】:

条件运算符是一个表达式:它有一个结果:

int a = cond ? 1 : 2;

但你不能这样使用它:

cond ? 1 : 2;

因为它不是StatementExpression;这与您无法编写任何内容的事实大致相同:

1;
2 * 3;
array[1];

因为它们只是没有任何用途。

StatementExpression 是一个表达式,您可以在其后弹出 ;,例如:

int i = 0;
someMethod(i++);  // Use of i++ as an expression.
i++;              // Use of i++ as a StatementExpression.

StatementExpressions的完整列表可以在in the language spec找到:

StatementExpression:
    Assignment 
    PreIncrementExpression 
    PreDecrementExpression 
    PostIncrementExpression 
    PostDecrementExpression 
    MethodInvocation 
    ClassInstanceCreationExpression

因此,您不必进行赋值:您可以以一种人为的方式使用条件运算符,例如:

(true ? new int[1] : null)[0]++;

(并不是说我以任何方式提倡这是好的代码,或者以任何方式有用;只是指出它是合法的)


至于您的其他问题:这些只是编译器实现特定的消息。您的编译器正在处理无效的语法,并尽最大努力帮助您,但它的工作并不特别好。

请注意,其他编译器(例如 Ideone 使用的编译器)会给出完全不同的消息。

第一种形式应该使用 if/else:

if (stuff.equals ("TV")) res= "Walter" else res = "White" ;

(顺便说一句,if 是一个声明)

第二个只是少了一些括号:

res = stuff.equals("TV")?(res="WALTER"):(res="WHITE");

尽管第二个和第三个操作数中的赋值无论如何都是多余的:

res = stuff.equals("TV")?"WALTER":"WHITE";    

【讨论】:

    猜你喜欢
    • 2013-08-04
    • 2017-07-16
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2015-06-12
    • 2013-03-17
    相关资源
    最近更新 更多