12

私はいくつかのコードのレビューを行っていて、Integer のラッパー クラスであるメンバー変数をポストインクリメントしている誰かのインスタンスに出くわしました。私は自分でそれを試してみましたが、それが機能することに本当に驚きました.

Integer x = 0; 
System.out.print(x++ + ", ");
System.out.print(x);

これは 、私が期待したもの0, 1ではありません。0, 0言語仕様を調べましたが、これをカバーするものは見つかりません。これが機能する理由と、複数のプラットフォーム間で安全であるかどうかを誰かに説明できますか? 私はこれが分解されると思っていたでしょう

Integer x = 0;
int temp1 = x.intValue();
int temp2 = temp1 + 1;
System.out.println(temp1);
temp1 = temp2;
System.out.println(x.intValue());

x = temp1;しかし、どうやら仕様には最終行の前に追加する何かがあるようです

4

5 に答える 5

15

プラットフォーム間で使用しても完全に安全です。この動作は、Java 言語仕様の §15.4.2 で指定されています(強調を追加)。

後置式の結果は、数値型に変換可能な型 ( §5.1.8 )の変数でなければなりません。そうしないと、コンパイル時エラーが発生します。

後置インクリメント式の型は、変数の型です。後置インクリメント式の結果は変数ではなく、値です。

実行時に、オペランド式の評価が突然完了すると、同じ理由で後置インクリメント式が突然完了し、インクリメントは発生しません。それ以外の場合、値 1 が変数の値に追加され、合計が variable に格納されます。加算の前に、値 1 と変数の値に対してバイナリ数値昇格 ( §5.6.2 ) が実行されます。必要に応じて、合計は縮小プリミティブ変換 ( §5.1.3 ) によって縮小されるか、格納される前に変数の型へのボックス化変換 ( §5.1.7 ) を受けます。後置インクリメント式の値は、新しい値が格納される前の変数の値です。

編集これは、サンプルコードで何が起こっているかをより正確に示しています。

Integer x = 0;
int temp = x.intValue();
x = temp + 1; // autoboxing!
System.out.println(temp + ", ");
System.out.println(x.intValue());
于 2012-11-07T23:34:55.380 に答える
1

Java 1.5 の時点で、Java は自動アンボックス化を実行して、必要に応じて「ラッパー型」などをInteger対応するプリミティブ型intに変換します。その後、インクリメント オペレータは、結果の に対して作業できますint

于 2012-11-07T23:34:47.080 に答える
1

サー テッド ホップによる回答は、数年または数年しかプログラミングをしていないプログラマーにとって非常に複雑なレベルです。

簡単な方法であなたの疑問を解消させてください

    Integer x=10;
    x++;
    System.out.println(x) ;

出力は11になります

++ポストまたはプリインクリメントのいずれかが内部でのみ1による加算を行っているため

つまり、x+1 は、実行して結果を同じ変数に戻す必要があるものです。

ie x=x+1;

+ 演算子はプリミティブのみを使用できますが、 x は object であることがわかったので、自動アンボックス化と自動ボックス化の概念があります。だから表現は

x.intValue()+1;//step 1 auto-unboxing

x=Integer.valueOf(x.intValue()+1);//step 2 auto-boxing

したがって、println ステートメント内の自動ボックス化解除の別のステップの後、出力は 11 になります。

于 2019-05-16T19:57:10.690 に答える
0

これは、オートボクシングと呼ばれる Java 5 の「新しい」機能であり、整数は必要に応じて in に変換され、その逆も同様です。Float、Double、Boolean などにも同じことが当てはまります。

便利な機能ですが、注意しないとパフォーマンスが大幅に低下する可能性があります

于 2012-11-07T23:36:18.310 に答える