我的问题用简单的英语:为什么这有效someObject.methodReturnsInteger().getClass()
(我不是真的意味着getClass
方法。只是一种适用于整数的方法。我真的不是表示一种特别返回Integer的方法。)但这不是++a++
?
换句话说,为什么(或如何)解析(或标记化)允许在第一个中使用返回值但在第二个中不使用?我的意思是,不应该这样解析后者:(++a)++
并使用++a
作为数字返回?
同样适用于:a+++++b
我希望这个问题很清楚。
感谢您的时间。
答案 0 :(得分:3)
表达式++a++
由3个部分组成,通过添加括号突出显示:(++(a))++
:
a
变量参考++X
前缀增量运算符(JLS §15.15.1)X++
后缀增量运算符(JLS §15.14.2)Javadoc说:
[X]必须是可转换(§5.1.8)到数字类型的类型的变量,否则会发生编译时错误。 [...] [prefix / postfix]增量表达式的结果不是变量,而是值。
因此,在您的表达式++a
中,因为a
是变量,但结果是值,因此(++a)++
不起作用。
a+++++b
不起作用,因为它被编译器解析为((a++)++)+b
,正如我们刚才所知,X++
需要一个变量。
它以这种方式解析,因为Java tokenizer将使用尽可能多的连续字符来形成有效的运算符。
现在,如果添加空格或括号,它可以工作,具体取决于您希望该表达式执行的操作。以下是完全相同的:
(a++)+(++b)
a+++(++b)
a++ + ++b
a+++ ++b
表达式someObject.methodReturnsInteger().getClass()
称为“method chaining”。
这是有效的,因为.
是一个左关联method invocation运算符,而.
左边的值只是一个对象(或静态方法调用的类,但是我们跳过那个。)
所以表达式解析如下:
( someObject . methodReturnsInteger() ) . getClass()
第一个.
有效,因为someObject
是一个对象。第二个.
有效,因为带括号的表达式的结果是一个对象。
方法链接很常见,使用builder pattern时非常好,例如
String s = new StringBuilder()
.append("Hello ")
.append(person.getFirstName())
.append(", please say hello to your father, ")
.append(person.getFather().getFirstName())
.append(".")
.toString();
答案 1 :(得分:2)
++
运算符不对数字起作用,它适用于变量。允许x++
,因为x
是变量。不允许++(x++)
这样的内容,因为(x++)
的结果是数字而不是变量。
答案 2 :(得分:1)
存储值的操作需要放置它的位置。您不能说(a*2)++
,因为表达式(a*2)
会返回临时结果。增加它将没有任何效果,因为临时结果会立即被丢弃。出于同样的原因,您不能说(a*2)=10
。
说++(a*2)
可能会更有意义,但是当你没有合适的位置时,这仍然表明你想要存储递增的值,所以语言设计师会而是你改为编写(a*2)+1
。
修复前和修复前增量操作符也返回临时结果,这就是为什么你不能两次或组合使用它们。