Java リフレクションのサンプル

Javaのリフレクションのサンプルです。

目次

サンプル リフレクションとは
  クラスの情報を取得する(クラス.class)
  クラスの情報を取得する(getClass)
  クラスの情報を取得する(Class.forName)
  メンバー変数を取得する(getDeclaredFields)
  メソッドを取得する(getDeclaredMethods)
  メソッドを実行する(invoke)
  privateのメンバー変数を変更する

リフレクションとは

Classクラス

Methodクラス

クラスの情報を取得する(クラス.class)

Class<?> 変数 = クラス.class;

クラス情報を取得したいクラス名に.classを追加して、クラス情報のインスタンス(Classクラス)を取得します。

package test1;

public class Test1 {
    public static void main(String[] args)   {
        
        Class<?> c = Color.class;

        System.out.println(c.getSimpleName()); //Color
        System.out.println(c.getPackage()); //package test1
        System.out.println(c.getName()); //test1.Color
    }
}
class Color {
}

6行目のColor.classで、13行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
8行目のgetSimpleNameメソッドは、クラス名を表示します。
9行目のgetPackageメソッドは、パッケージ名を表示します。
10行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。

 

クラスの情報を取得する(getClass)

Class<?> 変数 = インスタンスの変数.getClass();

インスタンスの変数とgetClassメソッドで、クラス情報のインスタンス(Classクラス)を取得します。

package test1;

public class Test1 {
    public static void main(String[] args)   {
        
        Color cl = new Color();
        Class<?> c = cl.getClass();

        System.out.println(c.getSimpleName()); //Color
        System.out.println(c.getPackage()); //package test1
        System.out.println(c.getName()); //test1.Color
    }
}
class Color {
}

6行目は、14行目のクラスをインスタンス化しています。
7行目は、getClassメソッドで14行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
getClassメソッドはObjectクラスにあるメソッドです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Object.html#getClass--

9行目のgetSimpleNameメソッドは、クラス名を表示します。
10行目のgetPackageメソッドは、パッケージ名を表示します。
11行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。

 

クラスの情報を取得する(Class.forName)

Class<?> 変数 = Class.forName(クラス);

Class.forNameと引数にクラスを指定して、クラス情報のインスタンス(Classクラス)を取得します。

package test1;

public class Test1 {
    public static void main(String[] args)   {

    	try {
			Class<?> c = Class.forName("test1.Color");
			
	        System.out.println(c.getSimpleName()); //Color
	        System.out.println(c.getPackage()); //package test1
	        System.out.println(c.getName()); //test1.Color
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}	
    }
}
class Color {
}

7行目のClass.forNameで、17行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
Class.forNameを使用する場合、try-catchでの例外処理が必要です。
9行目のgetSimpleNameメソッドは、クラス名を表示します。
10行目のgetPackageメソッドは、パッケージ名を表示します。
11行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。

 

メンバー変数を取得する(getDeclaredFields)

public Field[] getDeclaredFields()  throws SecurityException
public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException

メンバー変数を取得するサンプルです。

package test1;

import java.lang.reflect.Field;

public class Test1 {
    public static void main(String[] args)   {
        
        Class<Color> c = Color.class;

        Field[] aaa = c.getDeclaredFields();
        
        for (Field a : aaa) {
            System.out.println(a);
            //private java.lang.String test1.Color.moji
            //private java.lang.String test1.Color.name
        }
    }
}
class Color {
    private String moji = "色は";
    private String name;
}

10行目は、getDeclaredFieldsメソッドで19行目のクラスのメンバー変数を取得しています。
戻り値は、配列です。
12-16行目は、拡張for文で取得した値を表示しています。

 

メソッドを取得する(getDeclaredMethods)

public Method[] getDeclaredMethods() throws SecurityException

メソッドを取得するサンプルです。

package test1;

import java.lang.reflect.Method;

public class Test1 {
    public static void main(String[] args)   {
        
        Class<Color> c = Color.class;
        
        Method[] bbb = c.getDeclaredMethods();
        
        for (Method a : bbb) {
            System.out.println(a);
            //public java.lang.String test1.Color.getName()
            //public void test1.Color.setName(java.lang.String)
        }
    }
}
class Color {
	String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

10行目は、getDeclaredMethodsメソッドで19行目のクラスのメソッドを取得しています。
戻り値は、配列です。
12-16行目は、拡張for文で取得した値を表示しています。

 

メソッドを実行する(invoke)

メソッドを実行するサンプルです。

package test1;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test1 {
    public static void main(String[] args)   {
        
        Color color = new Color();
        Class<?> c1 = color.getClass();
        
        Method method1;
        Method method2;
        try {
            method1 = c1.getMethod("setName", String.class);
            
            method1.invoke(color, "オレンジ");
            
            method2 = c1.getMethod("getName");
            
            String result = (String) method2.invoke(color);
            
            System.out.println(result); //色はオレンジ
               
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
class Color {
    private String moji = "色は";
    private String name;

    public String getName() {
        return moji + name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

10行目は、getClassメソッドで38行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
15-21行目は、ClassクラスのgetMethodとMethodクラスのinvokeメソッドで42,45行目のメソッドを実行しています。

 

privateのメンバー変数を変更する

privateのメンバー変数を変更するサンプルです。

本来、privateのメンバー変数はクラスの外部から変更できませんが、リフレクションを使用すると可能になります。

package test1;

import java.lang.reflect.Field;

public class Test1 {
    public static void main(String[] args)   {
        
        Color color = new Color();
        Class<?> c1 = color.getClass();

        Field a1;
    
		try {
			a1 = c1.getDeclaredField("moji");
	        a1.setAccessible(true);
	        try {
				a1.set(color, "カラー");
				System.out.println(color.getName()); //カラー
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		} catch (NoSuchFieldException e1) {
			e1.printStackTrace();
		} catch (SecurityException e1) {
			e1.printStackTrace();
		}
    }
}
class Color {
    private String moji;
    public String getName() {
        return moji;
    }
}

9行目は、getClassメソッドで29行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
14行目は、getDeclaredFieldメソッドで引数に30行目のメンバ変数を指定しています。
15行目は、setAccessibleメソッドでアクセスできるようにしています。
17行目は、setメソッドでprivateの変数に値をセットしています。

関連の記事

Java インターフェースのサンプル(interface)
Java 委譲(デリゲート)のサンプル

△上に戻る