配列
配列とは
配列とは、同じ型の変数が連続してメモリ上に
置かれている状態のことを指します。
配列として変数を宣言すれば、
それによって変数にヘッダー情報を追加して、
配列の最大インデックス数とメモリのステップ情報を組み込むのです。
配列とポインタ
Javaは動的に確保したメモリのポイントをヘッダ情報を基にしながら
移動させることで配列を表現しています。
そのため、ポインタと配列は綿密な関係にあります。
メモリを動的に割り当てるということは、
其の動的に割り当てたメモリアドレスへのポイントを
する必要があります。
通常これがポインタなのですが、
Javaでは其のポインタの概念をなくし、
インデックスという考え方のみで良くなっています。
配列の作り方
配列を作るにはnewでメモリを動的に割り当て実装してあげます。
int[] i = new int[10];
これで10個分のint型の変数が出来ます。
また、int[] i;
i = new int[10];
このように、後から配列を実装することもできます。
インデックス
インデックスとは、配列を参照するための番号です。
簡単に言えば、配列の番号になります。
int[] i = new int[5];
これを使う時は、インデックス番号を入力して使います。
i[3] = 150;
このように、[]の中にint値を入れて、何番目の変数を参照するか
指定するわけです。
また、最初にint[] i = new int[10];として定数10を入れましたが、
このことを最大インデックスと言います。
この最大インデックスは不思議なことにi.lengthと入力したら、
int値として最大インデックス数を得ることが出来ます。
int a = i.length;
System.out.println(a);
//10
配列とポインタは綿密な関係にあることを先ほど述べました。
Javaでは其のポインタのコントロールが出来ないのですが、
C/C++では出来ます。
故に次のようなことが可能です。
int *i = new int[10];
*(i+4) = 10;
//i[4] = 10;と同じ
しかし、Javaではポインタコントロールが出来ないので、
このような操作が出来ません。
クラスと型
上記のように、i.lengthという風に記載すると、
その変数の最大インデックス数をint値で返しますが、
何故こういうことが出来るのでしょうか。
実はintというのもクラスの一部だからです。
また逆に言えば、クラス自体が型として扱うことが出来ます。
クラスの一部に、lengthというフィールドがあり、
newで作成した時に、コンストラクタでカウントされた情報が入っています。
※lengthは後々出てくるループ文や条件分岐などでよく使います。
最大インデックスに関する豆知識
何故こういう最大インデックスなどのヘッダー情報が
そのまま保存されるように定義されているのでしょうか。
もちろん、最大数を知るためというのもありますが、
本当の目的は、スコープが終了した場合、
変数や配列も同時に削除される時にコンパイラが使うからです。
作ったものは、作った分だけ削除されなければなりません。
つまり、最初に作った時の情報を元に削除を
行わなければならないからです。
デストラクタ
デストラクタとは何でしょうか。
コンストラクタの逆の処理をするところです。
コンストラクタは主に、フィールドを初期化するために使われます。
あるいは、動的にメモリを確保し、初期化する時も使われます。
デストラクタはそこで定義された動的にメモリを確保されたものに対して、
削除を働きかけることが出来るメソッドです。
また、コンストラクタはインスタンスを作成時に呼び出されますが、
デストラクタはインスタンスの削除を求められた時に、呼び出されます。
つまり{}スコープから出ようとしたらデストラクタが呼び出されるわけです。
Javaではデストラクタというものが存在しません。
デストラクタ処理はJavaのコンパイラが自動的に付け足してくれるのです。
そのため、動的に確保したメモリ領域の削除のことなど
意識することなく遣うことが出来ます。
※C++ではデストラクタがあり、
其の中でそれらの情報を削除するように仕向けなければならいのですが、
Javaの場合自動的にやってくれます。
前のJavaではこういったコンパイラに任せっきりの処理は、
かなりの速さのペナルティを負っていたそうなのですが、
最近のJavaは大分速くなってきているとのこと。