请注意引号JLS text前面的句子:
运算符之间的优先级由语法产生的层次结构管理。
Java语言的语法确定了可能的构造,并且隐式地确定了运算符的优先级。
即使您已经链接了princeton table个州,也是如此:
Java语言规范中没有显式的运算符优先级表。网络上和教科书中的不同表格在一些次要方面存在分歧。
因此,Java语言的语法不允许在赋值运算符的左边使用lambda表达式,同样,也不允许在->
的左边进行赋值。因此,尽管这些运算符之间没有任何歧义,但优先规则(尽管在JLS中已明确指出)变得毫无意义。
这允许编译,例如这样的宝石,毫不含糊:
static Consumer<String> C;
static String S;
public static void main(String[] args)
{
Runnable r;
r = () -> C = s -> S = s;
}
,
首先,让我们在这里解释实际问题。
假设您的定义类似
IntUnaryOperator op;
以下在语法上可以接受,并且可以按预期工作:
op = x -> x;
也就是说,我们在int
上有一个分配给op
变量的标识函数。但是,如果=
具有更高的优先级,我们希望Java将其解释为
(op = x) -> x;
这在语法上无效,因此应该是编译错误。因此,实际上分配没有比箭头高的优先级。
但是下面的命令也可以(假设t
是类型int
的类/实例变量):
op = x -> t = x;
这将进行编译,并且该函数(如果应用)将操作数的值分配给t
并返回它。
这意味着箭头的优先级没有比赋值t = x
高。否则它将被解释为
op = ( x -> t ) = x
很明显,这不会发生。
因此,这些操作似乎具有相同的优先级。而且,它们是右关联的。 JLS chapter 19的语法中暗示了这一点:
Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block
因此,lambda主体的右侧使我们返回到Expression
,这意味着我们可以在其中拥有一个(较高优先级)lambda,也可以在其中拥有一个(较高优先级)赋值。我的意思是“更高的优先级”是您越深入生产规则,表达式的计算就越早。
赋值运算符也是如此:
AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression
再一次,赋值的右边会使我们回到Expression
,因此我们可以在那里有一个lambda表达式或赋值。
因此,语法不必依赖JLS文本,而是为情况提供了明确定义。
本文链接:https://www.f2er.com/3022275.html