【Java】引数でクラスの型を受け取り、その引数で指定された型のクラスをインスタンス化する

【Java】引数でクラスの型を受け取り、その引数で指定された型のクラスをインスタンス化

目的

今回はJAVAメソッドの引数でインスタンス化されたクラスを渡す方法…ではなくクラスの型を引数として渡し、その引数で指定されたクラスの型でインスタンス化を行う方法です。

今回使用した環境

インターネット接続可能のオンラインの環境

64 ビット オペレーティング システム

Windows 10 22H2

Java 17

ソースコード

「目的」に書いてあることを読んでも何がやりたいのかわかりづらいため、実際のコードを例に見ていきます。

まずは以下のような赤鉛筆クラス( RedPencil )、青鉛筆クラス( BluePencil )があります。2つのクラスはインターフェース ( IPencil ) を実装しています。

また、2つのクラスはコンストラクタで名前 ( name ) だけが渡せるようになっています。

public class RedPencil implements IPencil {

	String name;  // 名前
	String color; // 色
	int price;    // 値段
	
	public RedPencil(String name) {this.name = name;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public String getColor() {return color;}
	public void setColor(String color) {this.color = color;}
	public int getPrice() {return price;}
	public void setPrice(int price) {this.price = price;}
}
public class BluePencil implements IPencil {

	String name;  // 名前
	String color; // 色
	int price;    // 値段
	
	public BluePencil(String name) {this.name = name;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public String getColor() {return color;}
	public void setColor(String color) {this.color = color;}
	public int getPrice() {return price;}
	public void setPrice(int price) {this.price = price;}
}
interface IPencil {

	String getName();
	void setName(String name);
	String getColor();
	void setColor(String color);
	int getPrice();
	void setPrice(int price);
}

ここで要件として「赤鉛筆クラス( RedPencil )、青鉛筆クラス( BluePencil )のインスタンス化の方法はほとんど変わらないので共通化したい」と依頼されたとします。

この依頼内容を実現するために、メソッド引数にクラスの型を指定することが有効となってきます。

依頼内容を実現したコードがこちらです。

public class PencilUtil {

	public static IPencil createPencil(Class<?> clazz, String name) {
		IPencil pencil = null;
		try {
			// 指定されたクラスの型で動的インスタンス化
			pencil = (IPencil) clazz.getDeclaredConstructor(String.class).newInstance(name);
			
			// 指定されたクラスの型によって色分けする
			if (clazz.equals(RedPencil.class)) {
				pencil.setColor("赤");
			} else if (clazz.equals(BluePencil.class)) {
				pencil.setColor("青");
			}
			
			// 価格はいつも100円
			pencil.setPrice(100);
			
		} catch (Exception e) {
			e.printStackTrace();
		}	

		return pencil;
	}
}

createPencilメソッドの引数にはクラスの型、名前を指定する仕様とします。そしてそのメソッドに指定されたクラスの型を元に動的にインスタンス化します。

キモとなるのは

clazz.getDeclaredConstructor(String.class).newInstance(name)

の箇所ですね。ここで引数で指定されたクラスの型、名前 (コンストラクタの引数)で該当クラスをインスタンス化しています。

動作確認のためのmainメソッドはこんな感じです。

public class PencilMain {

	public static void main(String[] args) {

		IPencil redPencil = PencilUtil.createPencil(RedPencil.class, "赤鉛筆");
		IPencil bluePencil = PencilUtil.createPencil(BluePencil.class, "青鉛筆");
		
		System.out.println(redPencil.getName());
		System.out.println(redPencil.getColor());
		System.out.println(redPencil.getPrice());
		
		System.out.println(""); // 出力を見やすくするためだけの改行
		
		System.out.println(bluePencil.getName());
		System.out.println(bluePencil.getColor());
		System.out.println(bluePencil.getPrice());
	}
}

動作確認

mainメソッドを実行すると赤鉛筆クラス( RedPencil )、青鉛筆クラス( BluePencil )がインスタンス化されていることが確認できました。


以上となります。

ここまでお読みいただきありがとうございました。

Java

Posted by だゆう