ここでは、Java 言語仕様に関する説明を示します。
整数リテラル ( JLS 3.10.1 ) のセクションには、次のように書かれています。
int 型の最大の 10 進数リテラルは2147483648
(2 31 ) です。0
からまでのすべての 10 進リテラルは2147483647
、int リテラルが出現する可能性がある場所に出現する可能性がありますが、リテラル2147483648
は単項否定演算子 のオペランドとしてのみ出現する可能性があります-
。
そう ...
最初のステートメントは、正当な整数リテラル値の代入です。コンパイルエラーなし。
2147483648
2 番目のステートメントは、前に単項否定演算子がないため、コンパイル エラーです。
3 番目のステートメントには、範囲外の整数リテラルが含まれていないため、その観点からはコンパイル エラーではありません。
代わりに、3 番目のステートメントは、JLS 15.18.2で説明されている 2 項加算式です。これは、整数の場合について次のように述べています。
整数の加算がオーバーフローした場合、結果は十分に大きな 2 の補数形式で表される数学的合計の下位ビットになります。オーバーフローが発生した場合、結果の符号は、2 つのオペランド値の数学的な合計の符号と同じではありません。
したがって、2147483647 + 1
オーバーフローして にラップし-2147483648
ます。
@Peter Lawrey は、3 番目のステートメントが "コンパイラによって書き直される" 可能性があることを (軽率に?) 示唆しており+2147483648
、その結果、コンパイル エラーが発生します。
これは正しくありません。
JLS には、定数式が非定数式とは異なる意味を持つ可能性があると述べているものは何もありません。それどころか、1 / 0
JLS のような場合には、物事をひっくり返して、式が異常終了するため、式は定数式ではないと言います。( JLS 15.28にあります)
JLS は、一部の Java コンストラクトがコンパイラによって異なることを意味するケースを回避するために非常に努力しています。たとえば、変数が使用される前に常に初期化されていると賢いコンパイラだけが推測できる場合を避けるために、「明確な代入」ルールに非常にこだわっています。これは、コードの移植性の観点からは良いことです。
コンパイラの実装者がプラットフォーム固有の処理を実行できる唯一の重要な領域は、同時実行性と Java メモリ モデルの領域です。これには、実用的な合理的な理由があります。それは、マルチスレッド Java アプリケーションをマルチコア/マルチプロセッサ ハードウェア上で高速に実行できるようにするためです。