最も低い優先順位演算子は、ラムダ式の矢印です(->)、フォロー割り当て演算子。
どちらの方向に進んだか(優先度の増加、優先度の減少)? -「フォローされている」とは、割り当てが(矢印演算子に対して)優先度が高いか低いかを意味します。 「最低」(矢印)は絶対的に最低を意味するため、増加すると思います。
私が理解しているように、矢印(->)はこの一番下にある必要があります プリンストン 演算子の優先順位表(つまり、すべての代入演算子の下にあります)。したがって、矢印(->)の優先度は0(ゼロ)です。 (その表のとおり)。
私の理解は正しいですか?
ExamTray 矢印の優先度は少なくとも割り当てと同じであると言われているようです...さらに、矢印の結合性が(割り当てとは異なり)左→右→右であることを明確にしました。矢印の結合性に関するJLSの引用は見つかりませんでした。
私はいつも、割り当ての優先順位が主に理由で最も低いと思っていました。
引用された JLSテキスト の前の文に注意してください。
演算子間の優先順位は、文法生成の階層によって管理されます。
Java言語の文法は、可能な構成を暗黙的に決定し、演算子の優先順位を示します。
プリンストンテーブル でも州をリンクしています:
Java言語仕様には、明示的な演算子優先順位表はありません。Webと教科書の異なる表は、いくつかの小さな点で一致していません。
したがって、Java言語の文法では、ラムダ式を代入演算子の左側に置くことはできません。同様に、->
の左側に代入することもできません。これらの演算子の間に曖昧さはありません。優先順位ルールは、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 19章 の文法から暗示されています。
Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block
したがって、ラムダ本体の右側からExpression
に戻ることができます。つまり、内部に(より高い優先度の)ラムダ、または(より高い優先度の)ラムダを割り当てることができます。 「優先度が高い」とは、プロダクションルールを深く掘り下げるほど、式が早く評価されるということです。
同じことが代入演算子にも当てはまります。
AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression
この場合も、割り当ての右側からExpression
に戻るので、ラムダ式または割り当てをここに置くことができます。
したがって、JLSテキストに依存するのではなく、文法は状況を明確に説明しています。