質問: new int [5]; ``` があったとして 「**new int [5];**」側はメモリ空間ではJVM(JAVA)固有領域である「**ヒープ領域**」という領域にて確保されますが、「**int a []**」側はメモリ空間では**どの領域で確保**されますか? JVM(JAVA)のメモリには「**JVM固有領域(ヒープ領域?)**」と「**OS固有領域**」の**2つがある**と言われており、「**OS固有領域**」内にはさらに「**Cピープ領域**」と「**スレッド領域**」「**スタック領域**」等がありますが、このうちの**どの領域に確保**されますか? 又、配列変数の「**int a []**」は「**int型やboolean型等**」の「**基本型変数**」とメモリ上の番地を代入する変数「**参照型変数**」を**足したようなもの**なんでしょうか? つまり、**配列変数の「int a [][]」は、基本型変数+参照型変数**はこれら等で**構成されている**のでしょうか? だとしたら、恐らく、「**int a[]**」側は「**スタック領域**」側に**確保される**のでしょうか? よろしくお願いします。
回答: Javaのあらゆる参照型の「実体」は全てヒープ上に確保されます。スタック上(ローカル変数の中身を置く場所)には実体への参照だけが置かれています。 > > int a[]側 > > > がローカル変数aのことであればそれはスタックということになります。 > > 配列変数の「int a [][]」は、基本型変数+参照型変数はこれら等で構成されているのでしょうか > > > 単に参照型の値を格納するための変数です。`int a[][]`の意味は`int[][]`型(それは参照型の一種)の変数aというだけの意味なのでString型などの普通の参照型変数と特に違いはありません。 ちなみにスタック領域、ヒープ領域の2種類だけを知っていればとりあえず充分な気がします。その2つをしっかり把握しておけばJavaプログラミング上の主な概念を理解するのに困ることはないと思います。(JNI、JITなどJVMの低水準な機構について知るという意味ではCヒープなども有効な知識だと思います) (スレッド領域とスタック領域を別領域として書かれていますが、多分同じもののような気がします。記事によってはスレッドスタック領域と書かれていたりします。スタックはスレッド毎にあるのは当然という感覚なので自分は普段スレッドスタック領域とは呼ばず単にスタックという用語を使いますが・・・本当の用語はどちらなのでしょうね。) 追記:コメントへの回答ですがここに記します。 > > これは、配列変数(参照型変数)が「基本型変数」をベースに(配列変数が)設計されているのでしょうか? > > > そういってよいと思います。配列は「同じ型の要素が複数並んだような型」ですがそれを表すのに「要素を表す型`T`」と「配列を表す記号`[]`」をくっつけて`T[]`と表現する言語仕様になっているわけですね。`int[]`というような記法ではなく`arrayOfInt`という型の名前とするような言語仕様もあり得ると思いますが、そんなふうにしてしまうと`int[][]`は`arrayOfArrayOfInt`、`int[][][]`は`arrayOfArrayOfArrayOfInt`などとしなくてはならず、収拾がつかなくなることは想像に難くありません。そんな設計は「無限に型の名前を用意しなくてはならないことになってしまう」ため採用されず「要素の型」と「配列を表す記号」を並べて書くことで「配列の型を表現する」ようにするのが合理的ということが納得できるのではないでしょうか? なお、基本型か参照型かについては「ある要素型Tの配列」「Tがプリミティブ型か参照型かには関係なく、常に参照型と決まっている」というのがJavaの規則です。 単なるintの値とint[]の値がスタック上どうなっているかを考えるとイメージしやすいと思います。 ``` スタック ヒープ +------+ | *------> +------------+----....----+ // 参照型(Stringの"abc")の実体はヒープ上にある +------+ |class=String|'a','b','c' | | ... | +------------+----....----+ +------+ | *------> +------------+-----+-----+ // int[]の値の実体もヒープ上にある +------+ |class=int[] | 1 | 2 | // --->だから参照型になる | ... | +------------+-----+-----+ +------+ | 1 | //上の配列の先頭要素を取り出して変数に入れれば要素の型はint(=プリミティブ型)なので +------+ //このようにスタック上に値が直接入る ``` プリミティブ型の値は「スタック上に直接入っていてヒープを一切使わない」のに対して、参照型の値は「実体がヒープ上にあり、スタック上にはヒープを指すアドレスorハンドルのような**参照値**を使う」というイメージです。