Arrow (->) operator precedence/priority is lowest, or priority of assignment/combined assignment is lowest?

蹲街弑〆低调 提交于 2020-01-01 04:01:31

问题


JLS:

The lowest precedence operator is the arrow of a lambda expression (->), followed by the assignment operators.

Followed in which direction (increasing priority, decreasing priority)? - "followed" means assignment has higher priority or lower priority (with respect to arrow operator)? I guess, in increasing, because "lowest" (for arrow) means absolutely lowest.

As I understand, arrow (->) should be at the very bottom of this Princeton operator precedence table (that is below all assignment operators), thus arrow (->) having 0 (zero) priority Level (as per that table).

Am I correct in my understanding?

ExamTray seems to say that arrow priority is at least same as assignment... Plus clarified that arrow associativity is Left->To->Right (unlike assignment). I didn't find any JLS quote for arrow associativity.

I always used to think that assignment priority is principally lowest for a reason.


回答1:


Note the sentence preceding the quoted JLS text:

Precedence among operators is managed by a hierarchy of grammar productions.

The grammar of the Java language determines which constructs are possible and implicitly, the operator precedence.

Even the princeton table you’ve linked states:

There is no explicit operator precedence table in the Java Language Specification. Different tables on the web and in textbooks disagree in some minor ways.

So, the grammar of the Java language doesn’t allow lambda expressions to the left of an assignment operator and likewise, doesn’t allow assignments to the left of the ->. So there’s no ambiguity between these operators possible and the precedence rule, though explicitly stated in the JLS, becomes meaningless.

This allows to compile, e.g. such a gem, without ambiguity:

static Consumer<String> C;
static String S;
public static void main(String[] args)
{
  Runnable r;
  r = () -> C = s -> S = s;
}



回答2:


First, let's explain the practical issue here.

Assuming you have a definition like

IntUnaryOperator op;

The following is syntactically accepted, and works as expected:

op = x -> x;

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;

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;

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

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

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

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.



来源:https://stackoverflow.com/questions/59068702/arrow-operator-precedence-priority-is-lowest-or-priority-of-assignment-com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!