6

Java で -128 から 127 までの整数を定義すると、新しいオブジェクトを作成する代わりに、既に作成されているオブジェクトが返されることをどこでも読んだことがあります。

初心者のプログラマーが整数オブジェクトを と比較して同じ数であるかどうかを確認できるようにする以外に、これを行う意味はありませんが、これは悪い==ことだと思います。==2 つの「異なる」オブジェクトの内容を==.

これが行われる理由について他に何か理由はありますか?それとも、JavaScript のオプションのセミコロンのように (私の観点から) 言語を設計するときの悪い決定ですか?

編集: ここで、彼らが動作を説明していることがわかります:整数定数プールの動作が 127 で変わるのはなぜですか?

なぜこの動作が発生するのかではなく、なぜこの動作をするように設計したのかを尋ねています。

4

2 に答える 2

11

これはFlyweight パターンと呼ばれ、メモリ使用量を最小限に抑えるために使用されます。

これらの数値は繰り返し使用される可能性が非常に高く、 のような autobox 型Integerは不変です (これは だけではありませんInteger)。それらをキャッシュすると、多くのインスタンスがなくなり、GC (ガベージ コレクション) の作業も削減されます。

JLS は5.1.7 でこれをカバーしています。 具体的には、次のように言ってボクシング コンバージョンを行います。

ボックス化された値 p が true、false、\u0000 ~ \u007f の範囲のバイト、または char、または -128 ~ 127 (両端を含む) の int または short の数値である場合、r1 および r2 を次の結果とします。 p の任意の 2 つのボクシング変換。r1 == r2 は常にそうです。

理想的には、指定されたプリミティブ値 p をボックス化すると、常に同一の参照が生成されます。実際には、これは既存の実装技術を使用して実現できない場合があります。上記のルールは実用的な妥協案です。上記の最後の節では、特定の共通値を常に区別できないオブジェクトにボックス化する必要があります。実装は、遅延または積極的にこれらをキャッシュする場合があります。他の値については、この定式化により、プログラマー側でボックス化された値の同一性に関する仮定ができなくなります。これにより、これらの参照の一部またはすべてを共有できます (必要ではありません)。

これにより、ほとんどの一般的なケースで、特に小さなデバイスで過度のパフォーマンスのペナルティを課すことなく、動作が望ましいものになることが保証されます。メモリ制限の少ない実装では、たとえば、すべての char 値と short 値、および -32K から +32K の範囲の int 値と long 値をキャッシュする場合があります。

于 2013-07-05T18:05:06.643 に答える
2

オブジェクトを作成するのは、シンボル テーブルから取得するよりも時間がかかると思います。さらに、私が間違っていなければ、ヒープ上のすべてのオブジェクトがヘッダー用に 24 バイトの追加スペースを占有します。現在、プログラマーが自分のプログラムを作成する場合、ほとんどの操作は小さな整数 (この場合は小さな整数) で行われます。そのため、多くのスペースを節約し、パフォーマンスを少し向上させることができます。

于 2013-07-05T17:55:43.000 に答える