箭头 (->) 运算符优先级/优先级最低,还是分配/组合分配的优先级最低?



JLS:

最低优先级运算符是 lambda 表达式的箭头 (->(, 后跟赋值运算符。

遵循哪个方向(增加优先级,降低优先级(? - "遵循"表示分配具有较高优先级或较低优先级(相对于箭头运算符(?我想,在增加中,因为"最低"(箭头(意味着绝对最低。

据我了解,箭头 (->( 应该位于普林斯顿运算符优先级表的最底部(低于所有赋值运算符(,因此箭头 (->( 具有 0(零(优先级(根据该表(。

我的理解正确吗?

ExamTray似乎说箭头优先级至少与分配相同...加澄清箭头关联性是左>到>右(与分配不同(。我没有找到任何关于箭头关联性的 JLS 引用。

我一直认为分配优先级通常是最低的,这是有原因的。

注意引用的JLS文本前面的句子:

运算符之间的优先级由语法生成的层次结构管理。

Java 语言的语法决定了哪些构造是可能的,并且隐式地决定了运算符优先级。

甚至你链接的普林斯顿表格也指出:

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

首先,让我们在这里解释一下实际问题。

假设你有一个定义,

比如
IntUnaryOperator op;

以下内容在语法上被接受,并按预期工作:

op = x -> x;

也就是说,我们在分配给op变量int上有一个恒等函数。但是,如果=具有更高的优先级,我们希望Java将其解释为。

(op = x) -> x;

这在语法上无效,因此应该是编译错误。因此,在实践中,赋值并不比箭头具有更高的优先级。

但以下内容也可以(假设t是类型为int的类/实例变量(:

op = x -> t = x;

这将编译,并且该函数(如果应用(将操作数的值分配给t并返回它。

这意味着箭头的优先级不高于分配t = x。否则会被解释为

op = ( x -> t ) = x

显然,事实并非如此。

因此,这些操作似乎具有相同的优先级。更重要的是,它们是右联的。这从JLS第19章的语法中得到了暗示:

Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block

所以 lambda 主体的右侧让我们回到Expression,这意味着我们可以在其中有一个(更高优先级的(lambda,或者一个(更高优先级的(赋值。我所说的"更高优先级"的意思是,您越深入地了解生产规则,表达式的评估就越早。

赋值运算符也是如此:

AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression

再一次,赋值的右侧将我们扔回Expression,因此我们可以在那里有一个 lambda 表达式或赋值。

因此,语法不是依赖于JLS文本,而是为我们提供了对情况的明确描述。

最新更新