3

クラスに整数配列があるとします。

public class Foo {
   private Integer[] arr = new Integer[20];
   .....

}

64 ビット アーキテクチャでは、これに必要なスペースは ~ (20*8+24) + 24*20 {参照に必要なスペース + 配列オーバーヘッド + オブジェクトに必要なスペース} です。

Javaが20個の整数オブジェクトすべてへの参照を保存するのはなぜですか? その最初のメモリ位置と配列内の項目数を知っていれば十分ではないでしょうか? (私もどこかで読んだように、配列内のオブジェクトがとにかく連続して配置されていると仮定します)。この種の実装の理由を知りたいです。これが初心者の質問である場合は申し訳ありません。

4

1 に答える 1

2

他のすべてのようにclassIntegerは参照型です。これは、参照を介して間接的にのみアクセスできることを意味します。参照型のインスタンスをフィールド、ローカル変数、コレクションのスロットなどに格納することはできません。常に参照を格納し、オブジェクト自体を個別に割り当てる必要があります。これにはさまざまな理由があります。

  • を表すことができる必要がありますnull
  • サブタイプの別のインスタンスで置き換えることができる必要があります(サブタイプが可能であると仮定すると、クラスは可能ではありませんfinal)。たとえば、Object[]実際には、サイズが大きく異なる任意の数の異なるクラスのインスタンスを格納できます。
  • 共有を維持する必要があります。たとえば、a[0] = a[1] = someObject; 3つすべてが同じオブジェクトを参照する必要があります。オブジェクトが可変である場合、これははるかに重要です(重要です)が、不変のオブジェクトでも、参照の等価性チェック(==)を介して違いを観察できます。
  • 参照の割り当てはアトミックである必要があるため(Javaメモリモデルを参照)、インスタンス全体をコピーすると、見た目よりもさらにコストがかかります。

これらおよび他の多くの制約があるため、(一般的に)実行可能な実装戦略は常に参照を格納することだけです。非常に特殊な状況では、JITコンパイラはオブジェクトを完全に割り当てることを避け、そのオブジェクトを直接(スタックなどに)格納する場合がありますが、これは実装の詳細があいまいであり、広く適用できません。これは完全を期すために、そしてそれがあたかもルールの素晴らしい例証であるためにのみ言及します。

于 2013-03-21T17:25:36.243 に答える