第十一章
メモリで見る基本型とクラス型の違い
クラス型(参照型)変数とメモリ
クラス型(参照型)変数とメモリの関係を紹介します。
目次
1. 類似品注意!!クラス変数とクラス型変数
本題に入る前に、1つだけご注意いただきたい言葉を紹介しておきます。
「クラス変数」と「クラス型変数」は別物です。
「クラス変数」と「クラス型(参照型)変数」は別物
- クラス変数
class 直下に宣言された staticな変数のこと。(今後出てきます。)
クラスに所属している変数です。
- クラス型(参照型)変数
インスタンス(クラスのコピーの様なもの)を代入する変数のこと。
参照型変数とも呼ばれます。
この章で扱うのは、クラス型(参照型)変数です。
ご留意くださいますようお願いいたします。
2. サンプルプログラム
前のページでは、基本型(プリミティブ型)変数とメモリの関係について見てきました。
それでは、クラス型の Stringや 配列ではどうでしょう。
Stringは、変数を宣言するときには代入される文字列の文字数は分かりません。
配列も、要素のデータ型は分かりますが要素数がいくつになるか決まっていません。
クラス型の場合、変数を宣言する時点では、メモリをどれだけ確保すればいいのかわからないのです。
そこで、クラス型変数は基本型変数とは違う仕組みになっています。
ここでは配列を例にしてクラス型変数を説明しましょう。
//Sample06_02.java
class Sample06_02 {
public static void main(String[] args){
int[] array_1;
array_1 = new int[4];
/*代入*/
array_1[0] = 1230;
array_1[1] = 1231;
array_1[2] = 1232;
array_1[3] = 1233;
for(int i=0; i<array_1.length; i++){
System.out.println(i + " = " + array_1[i]);
}
System.out.println("----------");
/*上書き代入*/
array_1[2] = 9992;
for(int i=0; i<array_1.length; i++){
System.out.println(i + " = " + array_1[i]);
}
}
}
コマンドライン
>javac Sample06_02.java
>java Sample06_02
0 = 1230
1 = 1231
2 = 1232
3 = 1233
----------
0 = 1230
1 = 1231
2 = 9992
3 = 1233
3. クラス型(参照型)変数の宣言
変数を宣言すると、メモリアドレスを記録するためのメモリだけを確保します。
このメモリモデルの環境は、メモリアドレスが 2byteで表現されているので 2byteを確保しています。
クラス型変数の宣言(int配列)
int[] array_1;
変数 array_1 と メモリのメモリアドレス 0x0038が紐づけられました。
基本型変数とは確保するサイズが違う。
メモリアドレスのサイズが 2byteの環境の場合は
何のクラスでも 2byteだけ確保する。
4. 変数にインスタンスを代入する
代入するときに、初めて必要分のメモリを確保します。
以下の図では、要素数 5の int配列に必要なメモリを、メモリアドレス 0x0050 に確保して、
そこに配列の実態である「インスタンス」を生成しました。
(↓図の青枠部分)
変数に紐づいたメモリには、「インスタンス」のメモリアドレスを記録します。(図では 0x0050)
これで、間接的に変数array_1と「インスタンス」がつながりました。
変数に紐づいたメモリに参照先のメモリアドレスを保存しているので、
クラス型は「参照型」とも呼ばれるのですね。
クラス型変数の代入とメモリの確保(int配列)
array_1 = new int[5];
インスタンスってこうゆうことっスか!!
これはスッキリ!
ちなみになんだが。
青エリアの「header」には、
lengthの情報などが入る。
緑エリアの「padding」は気にしないように。
new 演算子とインスタンス
- クラス型変数の値は「インスタンス」といいます。
配列の場合は、特に「配列インスタンス」と呼びます。
- new 演算子はインスタンスを生成します。
- インスタンスを変数に代入すると、
変数にはインスタンスのメモリアドレスが保存されます。
5. 要素に値を代入する
配列の各要素への代入
array_1[0] = 1230; ~
それぞれの要素に代入するときは、変数に保存されたメモリアドレスを参照します。
クラス型(参照型)変数は、代入された値を、参照先のアドレスとして処理します。
6. 要素に値を上書きしてみる
配列の各要素への上書き
array_1[2] = 9992;
普通に上書きだな。
それぞれの要素に対する動作は、要素が基本型であれば基本型と同じです。
確保されたメモリアドレスに直接値を代入します。
ちなみに。
要素がクラス型であれば、要素それぞれにインスタンスを生成することになります。
お疲れ様でした。