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

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;
}

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.