有谁能解释一下不同的间距如何影响一元算子?
int i = 1;
int j = i+ + +i; // this will print j=2
int k = i++ +i; // this will print k=3
int l = i+++i; // this will print l=3
int m = i++++i; // compile time error
答案 0 :(得分:43)
首先,让我们把它分成三个不能互动的案例:
int i = 1;
System.out.println(i+ + +i); // 2
int j = 1;
System.out.println(j++ +j); // 3
int k = 1;
System.out.println(k+++k); // 3
现在让我们用括号重写它们:
int i = 1;
System.out.println(i + (+(+i)));
int j = 1;
System.out.println((j++) + j);
int k = 1;
System.out.println((k++) + k);
这里我们不能使用前缀或后缀++运算符,因为我们在任何地方都没有++
的标记。相反,我们有一个二元+运算符和两个一元+运算符。
这个很简单:它就像它读取的那样,后缀为++运算符,后跟二元+运算符(不是+j
可能另外暗示的一元+运算符。)
最后一行被解析为(k++) + k
而不是k + (++k)
。两者都会在 this 情况下给出相同的答案,但我们可以通过使用两个不同的变量来证明哪个是:
int k1 = 1;
int k2 = 1;
System.out.println(k1+++k2); // Prints 2
System.out.println(k1); // Prints 2
System.out.println(k2); // Prints 1
正如您所看到的那样,k1
已经增加而不是k2
。
将k+++k
解析为k
,++
,+
,k
的令牌的原因归因于section 3.2 of the JLS,其中包括i++++i
:
每个步骤都使用尽可能长的翻译,即使结果最终没有形成正确的程序,而另一个词汇翻译也是如此。
相同的“尽可能长的翻译”规则将i
解析为++
,++
,i
,++
,这不是有效的表达式(因为{{1}}操作的结果是值,而不是变量。
答案 1 :(得分:13)
+
是运营商,++
是运营商,但+ +
不是 - + +
被解释为两个+
,而不是++
{1}}。因此,空间迫使您的代码以不同的方式进行解释。
+
既是一个二进制运算符,它添加两个数字,一个一元运算符不会改变一个数字(它只是为了与一元-
运算符保持一致)。
如果我们使用add
代替二进制+
,no-change
代替一元+
,而increment
代替++
则可能更清楚。
int j=i+ + +i
变为int j = i add no-change no-change i;
int k=i++ +i;
变为int k=i increment add i;
我怀疑int k = i+++i;
也变为int k = i increment add i;
但我没有用语言规范检查过这个。