前回に引き続き参照型のなかでも、配列について確認していきます。
前回の記事はこちら。 phoeducation.work
配列の正体
配列は一つの変数名で複数のデータを管理する仕組みでしたね。
実は、配列の正体はオブジェクトなのです。
言い換えると、配列は参照型です。
紛らわしいことに、配列の要素は普通の変数でも参照型でも構いません。
【配列】
public class ArraySample01{ public static void main(String[ ] args){ int[ ] a = new int[3]; a[0] = 9; a[1] = 4; a[2] = 5; for(int i = 0; i < 3; i++) System.out.println(a[i]); } }
実行結果
9 4 5
注目したいのは配列の宣言の部分です。
int[ ] a = new int[3];
aというのは配列名で、int型のデータではありません。
int型のデータになるのはa[0], a[1], a[2]といったところです。
では、aとは何でしょうか?
宣言のところをよく見てみてください。
Humanクラスなどと比較してみましょう。
int[ ] a = new int[3]; Human taro = new Human("太郎", 30, 175.5);
Humanクラスと比べると、「int[ ]クラスというクラスがあり、そのオブジェクトaを宣言した」と読むことができます。
実はまったくこの通りなのです。
int[ ]という、一見変わった名前のクラスとして扱うことができます。
もちろんchar型の配列ならchar[ ]クラス、double型の配列ならdouble[ ]クラスがあると考えて問題ありません。
配列の正体はオブジェクトなのです。
配列の参照値は[I@15db9742などのように出力されたはずです。
@マークの右側はハッシュ値、左側はクラス名のはずですが、[Iとは何でしょうか。
[は配列を意味し、Iは配列の要素がint型であることを示します。
他の方の配列も作り、@マークの左側がどうなるか確認してみましょう。
多次元配列
これは前項の「オブジェクトの配列」とまったく変わらないのですが、「配列の配列」を作ることによって多次元の配列を実現することができます。
【多次元配列を使う】
public class ArraySample04{ public static void main(String[ ] args){ int[ ][ ] a = new int[3][ ]; a[0] = new int[2]; a[1] = new int[4]; a[2] = new int[1]; a[0][0] = 6; a[0][1] = 7; a[1][0] = 1; a[1][1] = 3; a[1][2] = 8; a[1][3] = 9; a[2][0] = 4; for(int i = 0; i < a.length; i++){ for(int j = 0; j < a[i].length; j++){ System.out.println(a[i][j]); } } } }
実行結果
6 7 1 3 8 9 4
まず、3行目の段階で配列が1つ作られます。newを実行したのはまだ1回です。
配列の各要素も配列ですが、まだインスタンス化されていない状態です。
そのため、5行目~7行目でそれぞれをインスタンス化します。つまりnewを呼びます。
それでようやく全体が完成します。そのイメージは以下の通りです。
配列はオブジェクトなので、「配列の配列」は前項の「オブジェクトの配列」と同じです。
オブジェクトのところでもふれたように、ただ繰り返していくだけです。
三次元以上の配列も同様に作っていくことができます。
コマンドライン引数
main( )メソッドには引数があります。
見てのとおり、Stringオブジェクトの配列を受け取れるようになっています。
public static void main(String[ ] args){ }
では、main( )メソッドへの引数はどうやって渡すのでしょうか?
これはJavaVMを起動するとき、つまりクラスを実行するときに指定します。
Sampleというクラスを実行するとき、「実行の構成」を選択し、引数を指定します。
abc def ghi
などと文字列を追加できます。
スペースで区切ることによって、それぞれが文字列オブジェクトとして扱われます。
これを「コマンドライン引数」と言います。
では、これを使ったプログラムを見てみましょう。
【コマンドライン引数の利用】
public class Param01{ public static void main(String[ ] args){ System.out.println("先に入ったデータ : " + args[0]); System.out.println("後に入ったデータ : " + args[1]); } }
パッケージエクスプローラから「Param01.java」を選択し、[実行]メニューから[実行構成]を選択します。
[メイン]タブを選択し、[メイン・クラス]の[検索]をクリックして、実行したいクラス名を選択します。
[引数]タブを選択し、[プログラムの引数]に「abc def ghi」と入力し、実行をクリックします。
実行結果
先に入ったデータ : abc 後に入ったデータ : def
この例では、文字列abcがargs[0]、defがargs[1]、ghiがargs[2]に入ります。
プログラムの方ではargs[2]を無視していますが、引数としては渡されています。
逆に、引数が足りないとこのような例外を発生します。
ハードコーディング
コマンドライン引数を利用することで、「ハードコーディング」を減らすことができます。
ハードコーディングとは何か?
順を追って説明しましょう。
プログラムの中では様々なデータが扱われています。
例えば、以下のSample.javaというソースコードの中ではnumberという変数やnameというオブジェクトです。
このとき、違う値を使いたくなったときはどうしたら良いでしょうか?
public class Sample{ public static void main(String[ ] args){ int number = 17; String name = "斎藤 明夫"; System.out.println(number); System.out.println(name); } }
その場合は当然内容を書き換えてコンパイルするわけですが、「コンパイルをしなおす」というのは「今まで作ったアプリケーションはもう使えないので新しく作りなおした」という意味を持ちます。
このように、扱うデータが決まってしまっている、何をするか決まっていて変えられない、このようなことを「ハードコーディング」と言います。
一般的に、ハードコーディングはできるだけ避けるべきです。
プログラム中ではどんなデータを扱うか勝手に決めず、実行するたびに入力したりファイルから読み込んだりするのが一般的なデータの扱い方です。
まとめ
配列の正体
配列はオブジェクトなので、同様に参照型です。多次元配列
多次元配列は「配列の配列」を作ることによって実現できます。コマンドライン引数
main( )メソッドへの引数は、クラスを実行するときにスペースで区切って指定します。
参考図書
独学で挫折しそうになったら、オンラインプログラミングスクール