コンストラクタ (それは、newでオブジェクトを生成する命令)

前ページで作成した次のクラスがあるとします。

public class Record2{
	public String sho;	// 商品コード
	public short suu;	// 数量

	//n番目表示としてオペレータ用で画面表示する
	public void display(int n){
		System.out.printf("%4d番目レコード\n", n);
		System.out.printf("\t商品コード:%s\n", sho);
		System.out.printf("\t数量:%d\n", suu);
	}
	
	//商品コードと数量を引数で設定するメソッド
	public void init(String shoCode, int n)	{
		sho = shoCode;
		suu = (short)n;
	}
}

このクラスの利用例を示します。

public class Test{

	public static void main(String[] arg) throws Exception{
		Record2 a = new Record2();
		Record2 b = new Record2();
		
		a.init("A01", 4);//データ設定
		b.init("B01", 10);
		
		a.display(1);
		b.display(2);
	}
}

Record2() の表現は、コンストラクタと呼ばれ、new で生成するときに実行するものです。 これは、クラスの中で定義する(作る)ことができます。

引数ありコンストラクタ

以下は上記Record2クラスに引数ありコンストラクタを定義した例です。
(コンストラクタの定義は void などの型定義は無しで、戻り値も指定できません。 そして、 クラス名と 同じ名前 で作る必要があります)
 クラスの中で、フィールドやメソッド、コンストラクタを並べる順番は自由です。

public class Record2{
	public String sho;	// 商品コード
	public short suu;	// 数量

	//n番目表示としてオペレータ用で画面表示する
	public void display(int n){
		System.out.printf("%4d番目レコード\n", n);
		System.out.printf("\t商品コード:%s\n", sho);
		System.out.printf("\t数量:%d\n", suu);
	}
	
	//商品コードと数量を引数で設定するメソッド
	public void init(String shoCode, int n)	{
		sho = shoCode;
		suu = (short)n;
	}

	public Record2(String sho, int n){ //引数ありコンストラクタ
		init(  sho, n    );
	}
}

このコンストラクタを利用すると、前述の利用例は、以下のように簡単になります。(実行結果は同じです) つまり、オブジェクトを引数の指定で生成できる訳です。

public class Test{

	public static void main(String[] arg) throws Exception{
		Record2 a = new Record2("A01", 4);
		Record2 b = new Record2("B01", 10);
				
		a.display(1);
		b.display(2);
	}
}

但し、引数ありコンストラクタだけを作った時点で、 new Record2() の引数なしコンストラクタの 使用が不可能になります。(次のようなコンパイルエラーです。)
Test.java:行番号: シンボルを見つけられません。
シンボル: コンストラクタ Record2()

しかし引数なしコンストラクタを追加して作れば実行できるようになります。
例えば次のようなもので、これをRecord2に追加すればよいのです。

	public Record2(){//引数なしコンストラクタ
	}

上記のように何も命令を書かなくても、new の生成(コンストラクタの実行)により、 フィールドが基本型であれば0 に相当する値、参照型ならnullに自動設定されます。
一般に、コンストラクタではオブジェクト生成時に記憶しておきたいフィールドを設定する命令を書きます。 しかし、指定が必要なければ、このように中身を書かなくて構いません。

なお、 クラス内に1つもコンストラクタを作成しない場合は、 new クラス名(); のなにもしないコンストラクタの使用が可能でした。
このコンストラクタのことを特に、デフォルトコンストラクタと呼びます。
つまり、デフォルトコンストラクタは、自作のコンストラクタを作成した時により使えなくなり、 必要なら、引数なしのコンストラクタを自作しなければ ならないということです。

引数付きコンストラクタを利用した配列初期化例

次のように、引数付なしや、引数ありコンストラクタやを作ったクラスがあるとします。

public class Record2{
	public String sho;	// 商品コード
	public short suu;	// 数量

	//n番目表示としてオペレータ用で画面表示する
	public void display(int n){
		System.out.printf("%4d番目レコード\n", n);
		System.out.printf("\t商品コード:%s\n", sho);
		System.out.printf("\t数量:%d\n", suu);
	}
	
	//商品コードと数量を引数で設定するメソッド
	public void init(String shoCode, int n)	{
		sho = shoCode;
		suu = (short)n;
	}

	public Record2(){//引数なしコンストラクタ
	}
	
	public Record2(String sho, int n){ //引数ありコンストラクタ
		init(  sho, n    );
	}
}

これで、次のようにオブジェクトを生成できます。
Record2 a = new Recoed2();
Record2 b = new Recoed2("B02", 7);

そして、次のような配列の初期化でも使えるようになります。

public class Test{
	public static void main(String[] arg) throws Exception	{
		Record2[] a = new Record2[]{ 
			new Record2(),//引数なしコンストラクタ
			new Record2("A01", 5),//引数ありコンストラクタ
			new Record2("A03", 5),//引数ありコンストラクタ
			new Record2("B02", 3),//引数ありコンストラクタ
		};
		for (int i = 0; i < a.length; i++)	{
			a[i].display(i + 1);//表示
		}
	}
}

実行結果で分かるように、引数なしコンストラクタの生成は、 コンストラクタの定義内に 何も書かなかったので、フィールドの初期値のnullと0になっています。

Z:\Java>java Test
   1番目レコード
        商品コード:null
        数量:0
   2番目レコード
        商品コード:A01
        数量:5
   3番目レコード
        商品コード:A03
        数量:5
   4番目レコード
        商品コード:B02
        数量:3