Java:条件运算符的奇怪行为
Java: weird behavior of conditional operator
我有一个非常简单的 java class 来解决使用递归方法的解码方法。我看到条件运算符的这种奇怪行为,
package decodeways;
public class Solution {
public static void main(String[] args) {
System.out.println(numDecodings("1456"));
}
public static int numDecodings(String s) {
if(s.length()>0 && s.charAt(0)=='0')
return 0;
if(s.length()==0) return 1;
if(s.length()==1)
return 1;
int num1 = s.charAt(0)-'0';
int num2 = s.charAt(1)-'0';
int one = numDecodings(s.substring(1));
int two = s.length()>1?numDecodings(s.substring(2)):0;
int res = one
+ num1<3 && num2<7 ? two:0;
return res;
}
}
如果我加上括号,(num1<3 && num2<7 ? two:0)
那么一切都很好,但是如果我删除括号,就会得到不正确的结果。
调试过程中,one会被计算为1,two会被计算为1, res 也将是 1,但没有括号,res 的计算结果将是 0(附上截图),这是错误的来源。
我知道 java 中的运算符优先级,但在这种情况下我无法弄清楚为什么它显示不正确的行为,因为在下面的代码中:
int res = one
+ num1<3 && num2<7 ? two:0;
one + num1<3 是非法的
所以,java 足够聪明,不会混淆 (one + num1<3) 和 (num2<7 ? two:0) 需要单独考虑。
因此,根据我的理解,java 编译器唯一合法的可观察行为是自动将 num1<3 && num2<7 ? two:0
视为原子操作(如果我错了请纠正我),无论括号是否可用。
请多指教,加深理解
谢谢。
int res = one
+ num1<3 && num2<7 ? two:0;
相当于
int res = (((one + num1) < 3) && (num2 < 7)) ? two : 0;
?
之前的所有内容都包含在布尔表达式中,因为 ternary/conditional 运算符在这里的优先级最低(不包括赋值运算符),而 +
的优先级最高。
顺序是这样的:
+
,所以one + num1
先放在一起
<
,所以现在有 (one + num1) < 3
和 num2 < 7
&&
,之后你有 ((one + num1) < 3) && (num2 < 7)
- 和最后
?:
你似乎期望换行符让编译器认为 one
和 num1<3 && num2<7 ? two:0
是分开的,但它实际上只是忽略了所有空格。将括号放在此处是确保将 one
添加到条件运算符计算结果的唯一方法。
int res = one + (num1 < 3 && num2 < 7 ? two : 0);
我有一个非常简单的 java class 来解决使用递归方法的解码方法。我看到条件运算符的这种奇怪行为,
package decodeways;
public class Solution {
public static void main(String[] args) {
System.out.println(numDecodings("1456"));
}
public static int numDecodings(String s) {
if(s.length()>0 && s.charAt(0)=='0')
return 0;
if(s.length()==0) return 1;
if(s.length()==1)
return 1;
int num1 = s.charAt(0)-'0';
int num2 = s.charAt(1)-'0';
int one = numDecodings(s.substring(1));
int two = s.length()>1?numDecodings(s.substring(2)):0;
int res = one
+ num1<3 && num2<7 ? two:0;
return res;
}
}
如果我加上括号,(num1<3 && num2<7 ? two:0)
那么一切都很好,但是如果我删除括号,就会得到不正确的结果。
调试过程中,one会被计算为1,two会被计算为1, res 也将是 1,但没有括号,res 的计算结果将是 0(附上截图),这是错误的来源。
int res = one
+ num1<3 && num2<7 ? two:0;
one + num1<3 是非法的
所以,java 足够聪明,不会混淆 (one + num1<3) 和 (num2<7 ? two:0) 需要单独考虑。
因此,根据我的理解,java 编译器唯一合法的可观察行为是自动将 num1<3 && num2<7 ? two:0
视为原子操作(如果我错了请纠正我),无论括号是否可用。
请多指教,加深理解
谢谢。
int res = one
+ num1<3 && num2<7 ? two:0;
相当于
int res = (((one + num1) < 3) && (num2 < 7)) ? two : 0;
?
之前的所有内容都包含在布尔表达式中,因为 ternary/conditional 运算符在这里的优先级最低(不包括赋值运算符),而 +
的优先级最高。
顺序是这样的:
+
,所以one + num1
先放在一起<
,所以现在有(one + num1) < 3
和num2 < 7
&&
,之后你有((one + num1) < 3) && (num2 < 7)
- 和最后
?:
你似乎期望换行符让编译器认为 one
和 num1<3 && num2<7 ? two:0
是分开的,但它实际上只是忽略了所有空格。将括号放在此处是确保将 one
添加到条件运算符计算结果的唯一方法。
int res = one + (num1 < 3 && num2 < 7 ? two : 0);