Javaのリフレクション


Classクラスのインスタンスの取得

リフレクション機能を使うためには、Class クラスのインスタンスを取得する必要がある。
reflectionTestパッケージのTestClassというクラスの「Class クラスのインスタンス」を取得するには以下の3の方法がある。

(1)クラスよりClassクラスのインスタンスの取得を取得する。

Class<?> aClass=TestClass.class;

(2)クラス名(文字列)より取得

try {
	Class<?> aClass = Class.forName("reflectionTest.TestClass");
	...
} catch (ClassNotFoundException e) {
	e.printStackTrace();
}

(3)クラスのインスタンスより取得

TestClass testClass = new TestClass();
Class<?> aClass = testClass.getClass();

ここで「Class<?>」はClassクラスの総称型である。

Classクラスのインスタンスが取得できればこれを基に取得したクラスの様々な操作や情報の取得が可能になる。

クラスの情報の取得

以下のようなコードにてクラスに関する情報を取得して表示できる。

System.out.printf("Class: %s\n", aClass.getName());
System.out.printf("Package: %s\n", aClass.getPackage().getName());
System.out.printf("SimpleName: %s\n", aClass.getSimpleName());
System.out.printf("CanonicalName: %s\n", aClass.getCanonicalName());

スーパクラスおよびクラスの継承関係の取得

for(Class<?> superClass = aClass.getSuperclass();
	superClass!=null;superClass = superClass.getSuperclass())
	System.out.printf("Super Class: %s\n", superClass.getName());

以下の再帰メソッドにてインターフェースおよびインターフェースの継承関係を表示できる。

void printInterfaces(Class<?> aClass)
{
	for(Class<?> aInterface : aClass.getInterfaces()){
		System.out.printf("Interface: %s\n", aInterface.getName());
		printInterfaces(aInterface);
	}
}

インナークラスの列挙。

for(Class<?> innerClass : aClass.getClasses()){
	System.out.printf("InnerClass: %s, %s\n", innerClass,
			Modifier.toString(innerClass.getModifiers()));
}

クラスのアノテーション定義の列挙。

for(Annotation annotation : aClass.getDeclaredAnnotations()){
	System.out.printf("Annotation: %s, %s\n", annotation);
}

クラスのインスタンスの作成とコンストラクタ

クラスのインスタンスを生成するには以下のコードとなる。

Object instance;
try {
	instance = aClass.newInstance();
} catch (InstantiationException e) {
	e.printStackTrace();
} catch (IllegalAccessException e) {
	e.printStackTrace();
}

クラスのコンストラクタの列挙。

for(Constructor<?> constructor : aClass.getConstructors()){
	System.out.printf("Constructor: %s, %s\n", constructor.toGenericString(),
			Modifier.toString(constructor.getModifiers()));
}

クラスの引数なしコンストラクタを実行してクラスのインスタンスを生成。

Object instance;
Constructor<?> cunstructor;
try {
	cunstructor = aClass.getConstructor();
	try {
		instance = cunstructor.newInstance(new Object[]{ new Integer(123),  new String("hoge")});
	} catch (IllegalArgumentException e) {
		e.printStackTrace();
	} catch (InstantiationException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		e.printStackTrace();
	}
} catch (SecurityException e) {
	e.printStackTrace();
} catch (NoSuchMethodException e) {
	e.printStackTrace();
}

引数あり(int型引数とString型引数の)コンストラクタを実行してクラスのインスタンスを生成。

Object instance;
Constructor<?> cunstructor;
try {
		cunstructor = aClass.getConstructor(int.class, String.class);
	try {
		instance = cunstructor.newInstance(123,  "hoge");
	} catch (IllegalArgumentException e) {
		e.printStackTrace();
	} catch (InstantiationException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		e.printStackTrace();
	}
} catch (SecurityException e) {
	e.printStackTrace();
} catch (NoSuchMethodException e) {
	e.printStackTrace();
}

フィールドの操作

フィールドの列挙。

for(Field field : aClass.getDeclaredFields()){
	System.out.printf("Field: %s, %s\n", field.getName(),
			Modifier.toString(field.getModifiers()));
}

フィールドの操作。

try {
	// インスタンスフィールド
	Field field;
	instance = aClass.newInstance();

	field = aClass.getDeclaredField("instanceField");
	field.set(instance, "bar");
	String s = (String)field.get(instance);
	System.out.printf("instanceField : %s\n", s);

	// static フィールド
	field = aClass.getDeclaredField("staticField");
	field.set(null, 88);
	int i = (Integer)field.get(null);
	System.out.printf("staticField : %d\n", i);

	// private フィールド
	field = aClass.getDeclaredField("prop2");
	field.setAccessible(true);	// privateメンバへのアクセスを許可
	field.set(instance, "huga");
	s = (String)field.get(instance);
	System.out.printf("prop2 : %s\n", s);
} catch (Exception e) {
	e.printStackTrace();
}

メソッドの操作

メソッドの列挙。

for(Method method : aClass.getDeclaredMethods()){
	System.out.printf("Method: %s, %s\n", method.getName(),
			Modifier.toString(method.getModifiers()));
}

メソッドの操作。

Method method;
try {
	// staticメソッド(引数なし)
	method = aClass.getMethod("staticMethod");
	System.out.printf("TestClass.staticMethod() : %s\n",
			method.invoke(null));
	// インスタンスメソッド(引数なし)
	instance = aClass.newInstance();
	method = instance.getClass().getMethod("method1");
	System.out.printf("testClass.method1() : %s\n",
			method.invoke(instance));
	// インスタンスメソッド(引数あり)
	method = instance.getClass().getMethod("method2", String.class, int.class);
	System.out.printf("testClass.method2(\"fuga\", 555) : %s\n",
			method.invoke(instance, "huga", 555));
	// インスタンスメソッド(private)
	method = instance.getClass().getDeclaredMethod("method3");
	method.setAccessible(true);	// privateメンバへのアクセスを許可
	System.out.printf("testClass.method3() : %s\n",
			method.invoke(instance));
} catch (Exception e) {
	e.printStackTrace();
}

プロパティの操作

PropertyDescriptor propertyDescriptor;
try {
	propertyDescriptor = new PropertyDescriptor("prop1", aClass);
	instance = aClass.newInstance();

	//セッターメソッド操作
	Method setterMethod = propertyDescriptor.getWriteMethod();
	setterMethod.invoke(instance, -111);

	//ゲッターメソッド操作
	Method getterMethod = propertyDescriptor.getReadMethod();
	int i = (Integer) getterMethod.invoke(instance);
	System.out.println(i);
} catch (Exception e) {
	e.printStackTrace();
}

サンプルに使用したソースコードと実行結果

動作確認に使用したコードと実行結果は以下のとおりである。

ReflectionTest.java》

package reflectionTest;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectionTest {
	public static void main(String args[]) {
		//Package.getPackage(name);

		Class<?> aClass;
		aClass=TestClass.class;
		PrintClassInfo(aClass);

		try {
			aClass = Class.forName("reflectionTest.TestClass");
			PrintClassInfo(aClass);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		TestClass testClass = new TestClass();
		aClass = testClass.getClass();
		PrintClassInfo(aClass);

		Object instance;
		try {
			instance = aClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

		Constructor<?> cunstructor;
		try {
			cunstructor = aClass.getConstructor(new Class[]{int.class,String.class});
			//cunstructor = aClass.getConstructor(int.class, String.class);
			try {
				instance = cunstructor.newInstance(new Object[]{ new Integer(123),  new String("hoge")});
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		// フィールド操作
		try {
			// インスタンスフィールド
			Field field;
			instance = aClass.newInstance();

			field = aClass.getDeclaredField("instanceField");
			field.set(instance, "bar");
			String s = (String)field.get(instance);
			System.out.printf("instanceField : %s\n", s);

			// static フィールド
			field = aClass.getDeclaredField("staticField");
			field.set(null, 88);
			int i = (Integer)field.get(null);
			System.out.printf("staticField : %d\n", i);

			// private フィールド
			field = aClass.getDeclaredField("prop2");
			field.setAccessible(true);	// privateメンバへのアクセスを許可
			field.set(instance, "huga");
			s = (String)field.get(instance);
			System.out.printf("prop2 : %s\n", s);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// メソッド操作
		Method method;
		try {
			// staticメソッド(引数なし)
			method = aClass.getMethod("staticMethod");
			System.out.printf("TestClass.staticMethod() : %s\n",
					method.invoke(null));
			// インスタンスメソッド(引数なし)
			instance = aClass.newInstance();
			method = instance.getClass().getMethod("method1");
			System.out.printf("testClass.method1() : %s\n",
					method.invoke(instance));
			// インスタンスメソッド(引数あり)
			method = instance.getClass().getMethod("method2", String.class, int.class);
			System.out.printf("testClass.method2(\"fuga\", 555) : %s\n",
					method.invoke(instance, "huga", 555));
			// インスタンスメソッド(private)
			method = instance.getClass().getDeclaredMethod("method3");
			method.setAccessible(true);	// privateメンバへのアクセスを許可
			System.out.printf("testClass.method3() : %s\n",
					method.invoke(instance));
		} catch (Exception e) {
			e.printStackTrace();
		}

		// プロパティ操作
		PropertyDescriptor propertyDescriptor;
		try {
			propertyDescriptor = new PropertyDescriptor("prop1", aClass);
			instance = aClass.newInstance();

			//セッターメソッド操作
			Method setterMethod = propertyDescriptor.getWriteMethod();
			setterMethod.invoke(instance, -111);

			//ゲッターメソッド操作
			Method getterMethod = propertyDescriptor.getReadMethod();
			int i = (Integer) getterMethod.invoke(instance);
			System.out.println(i);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	static void PrintClassInfo(Class<?> aClass)
    {
		System.out.printf("Class: %s\n", aClass.getName());
		System.out.printf("Package: %s\n", aClass.getPackage().getName());
		System.out.printf("SimpleName: %s\n", aClass.getSimpleName());
		System.out.printf("CanonicalName: %s\n", aClass.getCanonicalName());

		for(Class<?> superClass = aClass.getSuperclass();
			superClass!=null;superClass = superClass.getSuperclass())
			System.out.printf("Super Class: %s\n", superClass.getName());

		printInterfaces(aClass);

		for(Constructor<?> constructor : aClass.getConstructors()){
			System.out.printf("Constructor: %s, %s\n", constructor.toGenericString(),
					Modifier.toString(constructor.getModifiers()));
		}

		for(Field field : aClass.getDeclaredFields()){
			System.out.printf("Field: %s, %s\n", field.getName(),
					Modifier.toString(field.getModifiers()));
		}

		for(Method method : aClass.getDeclaredMethods()){
			System.out.printf("Method: %s, %s\n", method.getName(),
					Modifier.toString(method.getModifiers()));
		}

		for(Annotation annotation : aClass.getDeclaredAnnotations()){
			System.out.printf("Annotation: %s, %s\n", annotation);
		}

		for(Class<?> innerClass : aClass.getClasses()){
			System.out.printf("InnerClass: %s, %s\n", innerClass,
					Modifier.toString(innerClass.getModifiers()));
		}
    }

	static void printInterfaces(Class<?> aClass)
    {
		for(Class<?> aInterface : aClass.getInterfaces()){
			System.out.printf("Interface: %s\n", aInterface.getName());
			printInterfaces(aInterface);
		}
    }
}

《TestClass.java》

package reflectionTest;

public class TestClass extends TestClassSuper
	implements ITestInterface1,ITestInterface2{

    public class NestNestTestClass { }

	public static int staticField=33;
	public String instanceField="xxx";

    public String method1 ()
    {
        return prop2 + String.valueOf(prop1);
    }

    public String method2 (String s, int i)
    {
        return s + String.valueOf(i);
    }

	static public String staticMethod ()
    {
        return TestClass.class.getName();
    }

	private int method3 ()
    {
        return 999;
    }

    public TestClass () { }

    public TestClass (int i, String s)
    {
    	prop1=i;
    	prop2=s;
    }

    private int prop1=99;
	private String prop2="abc";

	public int getProp1() {
		return prop1;
	}

	public void setProp1(int prop1) {
		this.prop1 = prop1;
	}

	public String getProp2() {
		return prop2;
	}

	public void setProp2(String prop2) {
		this.prop2 = prop2;
	}
}

《TestClassSuper.java》

package reflectionTest;

public class TestClassSuper {

}

《ITestInterface1.java》

package reflectionTest;

public interface ITestInterface1 {

}

《ITestInterface2.java》

package reflectionTest;

public interface ITestInterface2 extends ITestInterface2Super{

}

《ITestInterface2Super.java》

package reflectionTest;

public interface ITestInterface2Super {

}

プログラムの実行結果

Class: reflectionTest.TestClass
Package: reflectionTest
SimpleName: TestClass
CanonicalName: reflectionTest.TestClass
Super Class: reflectionTest.TestClassSuper
Super Class: java.lang.Object
Interface: reflectionTest.ITestInterface1
Interface: reflectionTest.ITestInterface2
Interface: reflectionTest.ITestInterface2Super
Constructor: public reflectionTest.TestClass(int,java.lang.String), public
Constructor: public reflectionTest.TestClass(), public
Field: staticField, public static
Field: instanceField, public
Field: prop1, private
Field: prop2, private
Method: staticMethod, public static
Method: method1, public
Method: method2, public
Method: method3, private
Method: getProp1, public
Method: setProp1, public
Method: getProp2, public
Method: setProp2, public
InnerClass: class reflectionTest.TestClass$NestNestTestClass, public
Class: reflectionTest.TestClass
Package: reflectionTest
SimpleName: TestClass
CanonicalName: reflectionTest.TestClass
Super Class: reflectionTest.TestClassSuper
Super Class: java.lang.Object
Interface: reflectionTest.ITestInterface1
Interface: reflectionTest.ITestInterface2
Interface: reflectionTest.ITestInterface2Super
Constructor: public reflectionTest.TestClass(int,java.lang.String), public
Constructor: public reflectionTest.TestClass(), public
Field: staticField, public static
Field: instanceField, public
Field: prop1, private
Field: prop2, private
Method: staticMethod, public static
Method: method1, public
Method: method2, public
Method: method3, private
Method: getProp1, public
Method: setProp1, public
Method: getProp2, public
Method: setProp2, public
InnerClass: class reflectionTest.TestClass$NestNestTestClass, public
Class: reflectionTest.TestClass
Package: reflectionTest
SimpleName: TestClass
CanonicalName: reflectionTest.TestClass
Super Class: reflectionTest.TestClassSuper
Super Class: java.lang.Object
Interface: reflectionTest.ITestInterface1
Interface: reflectionTest.ITestInterface2
Interface: reflectionTest.ITestInterface2Super
Constructor: public reflectionTest.TestClass(int,java.lang.String), public
Constructor: public reflectionTest.TestClass(), public
Field: staticField, public static
Field: instanceField, public
Field: prop1, private
Field: prop2, private
Method: staticMethod, public static
Method: method1, public
Method: method2, public
Method: method3, private
Method: getProp1, public
Method: setProp1, public
Method: getProp2, public
Method: setProp2, public
InnerClass: class reflectionTest.TestClass$NestNestTestClass, public
instanceField : bar
staticField : 88
prop2 : huga
TestClass.staticMethod() : reflectionTest.TestClass
testClass.method1() : abc99
testClass.method2("fuga", 555) : huga555
testClass.method3() : 999
-111

 

Javaの参考書 /  Javaの資格・問題集 /  eclipseの参考書 /  プログラム開発の本

 

ページのトップへ戻る