メソッドまたはクラス スコープでは、次の行がコンパイルされます (警告あり)。
int x = x = 1;
変数がデフォルト値を取得するクラススコープでは、次のようにすると「未定義の参照」エラーが発生します。
int x = x + 1;
最初x = x = 1
は同じ「未定義の参照」エラーで終わるべきではありませんか? それとも、2行目int x = x + 1
はコンパイルする必要がありますか? または、私が見逃しているものがありますか?
メソッドまたはクラス スコープでは、次の行がコンパイルされます (警告あり)。
int x = x = 1;
変数がデフォルト値を取得するクラススコープでは、次のようにすると「未定義の参照」エラーが発生します。
int x = x + 1;
最初x = x = 1
は同じ「未定義の参照」エラーで終わるべきではありませんか? それとも、2行目int x = x + 1
はコンパイルする必要がありますか? または、私が見逃しているものがありますか?
int x = x = 1;
と同等です
int x = 1;
x = x; //warning here
にいる間
int x = x + 1;
最初に計算する必要x+1
がありますが、x の値が不明であるため、エラーが発生します (コンパイラは x の値が不明であることを認識しています)。
Java や現代の言語では、代入は右から来ます。
2 つの変数 x と y があるとします。
int z = x = y = 5;
このステートメントは有効であり、これがコンパイラーがそれらを分割する方法です。
y = 5;
x = y;
z = x; // which will be 5
しかし、あなたの場合
int x = x + 1;
このように分割されるため、コンパイラは例外を与えました。
x = 1; // oops, it isn't declared because assignment comes from the right.
int x = x = 1;
等しくない:
int x;
x = 1;
x = x;
javap が再び役立ちます。これらは、このコード用に生成された JVM 命令です。
0: iconst_1 //load constant to stack
1: dup //duplicate it
2: istore_1 //set x to constant
3: istore_1 //set x to constant
もっと好き:
int x = 1;
x = 1;
未定義の参照エラーをスローする理由はありません。初期化の前に変数が使用されるようになったため、このコードは仕様に完全に準拠しています。実際、変数の使用はまったくなく、代入だけです。そして、JIT コンパイラーはさらに進んで、そのような構造を排除します。正直なところ、このコードが JLS の変数の初期化と使用に関する仕様とどのように関連しているかはわかりません。使用感問題なし。;)
私が間違っている場合は修正してください。多くのJLS段落を参照する他の回答が非常に多くのプラスを収集する理由がわかりません。これらの段落は、このケースとは何の共通点もありません。シリアル課題は 2 つだけで、それ以上はありません。
書くと:
int b, c, d, e, f;
int a = b = c = d = e = f = 5;
に等しい:
f = 5
e = 5
d = 5
c = 5
b = 5
a = 5
右端の式は、再帰なしで変数に 1 つずつ割り当てられます。好きなように変数をいじることができます:
a = b = c = f = e = d = a = a = a = a = a = e = f = 5;
コードの最初の部分に=
は、プラスの代わりに秒が含まれています。これはどこでもコンパイルされますが、2 番目のコードはどちらの場所でもコンパイルされません。
コードが実際にどのように動作するかにより、コード行は警告付きでコンパイルされません。コードを実行するとint x = x = 1
、Java は最初に変数x
を定義どおりに作成します。次に、割り当てコード ( x = 1
) を実行します。はすでに定義されているためx
、システムは 1 に設定してもエラーはありませんx
。これは値 1 を返しますx
。そのため、x
最終的には 1 に設定されます
。Java は基本的に、次のようにコードを実行します。
int x;
x = (x = 1); // (x = 1) returns 1 so there is no error
ただし、コードの 2 番目の部分ではint x = x + 1
、+ 1
ステートメントを定義する必要x
がありますが、その時点ではまだ定義されていません。割り当てステートメントは常に の右側のコードが最初に実行されることを意味するため、が定義されてい=
ないため、コードは失敗します。x
Java は次のようなコードを実行します。
int x;
x = x + 1; // this line causes the error because `x` is undefined