Cod*_*ete 17 java specifications operator-precedence language-lawyer java-8
JLS:
的最低优先级操作者是lambda表达式的箭头( - >) ,随后由赋值运算符。
遵循哪个方向(增加优先级,减少优先级)?-“跟随”是指分配的优先级较高还是较低(相对于箭头运算符)?我猜想,这是因为“最低”(箭头)表示绝对最低。
据我了解,箭头(->)应该位于此Princeton运算符优先级表的最底部(在所有赋值运算符的下方),因此箭头(->)的优先级为0(零)(根据该表)。
我的理解正确吗?
ExamTray似乎说箭头优先级至少与分配相同。此外,还阐明了箭头的关联性是Left-> To-> Right(与分配不同)。我没有找到JLS的箭头关联性报价。
我一直认为分配优先级原则上最低。
Hol*_*ger 11
请注意引用的JLS文本前面的句子:
运算符之间的优先级由语法产生的层次结构管理。
Java语言的语法确定了可能的构造,并且隐式地确定了运算符的优先级。
甚至您已链接的princeton表也指出:
Java语言规范中没有显式的运算符优先级表。网络上和教科书中的不同表格在一些次要方面存在分歧。
因此,Java语言的语法不允许在赋值运算符的左侧使用lambda表达式,同样,也不允许在->。运算符的左侧进行赋值。因此,尽管这些操作符之间没有歧义,但优先规则(尽管在JLS中已明确指出)变得毫无意义。
这样可以毫无歧义地编译例如这样的gem:
static Consumer<String> C;
static String S;
public static void main(String[] args)
{
Runnable r;
r = () -> C = s -> S = s;
}
Run Code Online (Sandbox Code Playgroud)
First, let's explain the practical issue here.
Assuming you have a definition like
IntUnaryOperator op;
Run Code Online (Sandbox Code Playgroud)
The following is syntactically accepted, and works as expected:
op = x -> x;
Run Code Online (Sandbox Code Playgroud)
That is, we have an identity function on int assigned to the op variable. But if = had a higher priority, we'd expect Java to interpret this as
(op = x) -> x;
Run Code Online (Sandbox Code Playgroud)
Which is not syntactically valid, thus should be a compile error. Hence, assignment does not, in practice, have higher precedence than the arrow.
But the following is also OK (assume t is a class/instance variable of type int):
op = x -> t = x;
Run Code Online (Sandbox Code Playgroud)
This compiles, and the function, if applied, assigns the value of the operand to t and also returns it.
This means that the arrow doesn't have higher precedence than the assignment t = x. Otherwise it would have been interpreted as
op = ( x -> t ) = x
Run Code Online (Sandbox Code Playgroud)
and clearly, this is not what happens.
So it seems that the operations have equal precedence. What's more, that they are right-associative. This is implied from the grammar at JLS chapter 19:
Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block
Run Code Online (Sandbox Code Playgroud)
So the right side of the lambda body gets us back to Expression, which means we can either have a (higher priority) lambda inside it, or a (higher priority) assignment in it. What I mean by "higher priority" is that the deeper you go through the production rules, the earlier the expression will be evaluated.
The same is true for the assignment operator:
AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression
Run Code Online (Sandbox Code Playgroud)
Once again, the right side of the assignment throws us back to Expression, so we can have a lambda expression or an assignment there.
So rather than relying on the JLS text, the grammar gives us a well defined description of the situation.
| 归档时间: |
|
| 查看次数: |
564 次 |
| 最近记录: |