Javaのリフレクションを使ってインスタンス生成を試す
リフレクションの勉強をします。リフレクションといってもカバーする領域が広い(応用範囲が広い)ので、今回はインスタンスの生成に関するリフレクションについて勉強します。
Classオブジェクトを取得
- クラスリテラルを使用する
- オブジェクトに対して、getClassメソッドを使う
- staticメソッドのClass.forNameを使用して、完全修飾名により検索する
- クラスローダから取得する
クラスリテラルを使用する
テスト用クラスとして以下を準備します。Foo.java
public class Foo {
private String bar;
private Integer hoge;
private Double fuga;
static {
System.out.println("static block.");
}
public Foo() {
System.out.println("constructor.");
}
protected Foo(String bar) {
this.bar = bar;
}
Foo(Integer hoge) {
this.hoge = hoge;
}
private Foo(Double fuga) {
this.fuga = fuga;
}
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
public int publicMethod() {
return 1;
}
protected int protectedMethod() {
return 2;
}
int defaultMethod() {
return 3;
}
private int privateMethod() {
return 4;
}
public static int staticMethod() {
return 11;
}
@Override
public String toString() {
return "Foo [bar=" + bar + "]";
}
}
Class<? extends Foo> clazz1 = Foo.class;
オブジェクトに対して、getClassメソッドを使う
Foo foo = new Foo(); Class<? extends Foo> clazz2 = foo.getClass();
staticメソッドのClass.forNameを使用して、完全修飾名により検索する
Class<Foo> clazz3; try { clazz3 = (Class<Foo>) Class.forName("jp.co.sample.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
クラスローダから取得する
ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class<?> clazz4; try { clazz4 = loader.loadClass("jp.co.sample.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
Classオブジェクトからインスタンス生成
リフレクションでインスタンスを生成するには、Constructorオブジェクトを取得し、Constructor#newInstance()を使います。
確認用テストコード
@Test public void クラスオブジェクトからインスタンス生成1() throws Exception { Class<Foo> clazz = Foo.class; Foo foo = clazz.getConstructor().newInstance(); assertThat(foo, is(instanceOf(Foo.class))); } @Test public void クラスオブジェクトからインスタンス生成2() throws Exception { Foo object = new Foo(); Class<? extends Foo> clazz = object.getClass(); Foo foo = clazz.getConstructor().newInstance(); assertThat(foo, is(instanceOf(Foo.class))); } @SuppressWarnings("unchecked") @Test public void クラスオブジェクトからインスタンス生成3() throws Exception { Class<Foo> clazz = null; try { clazz = (Class<Foo>) Class.forName("jp.co.sample.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Foo foo = clazz.getConstructor().newInstance(); assertThat(foo, is(instanceOf(Foo.class))); } @SuppressWarnings("unchecked") @Test public void クラスオブジェクトからインスタンス生成4() throws Exception { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class<Foo> clazz = null; try { clazz = (Class<Foo>) loader.loadClass("jp.co.sample.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Foo foo = clazz.getConstructor().newInstance(); assertThat(foo, is(instanceOf(Foo.class))); }