Javaで,private変数・privateメソッド・privateコンストラクタを,外部から呼び出そう (リフレクションの方法)
Javaでは,クラス内でprivate宣言されたメンバは,普通は外部からは呼び出せない。
しかし,リフレクションを使えば,それも可能。
本エントリでは,以下のサンプルコードを示す。
(1)
- privateなインスタンス変数の呼び出し方法
- privateなクラス変数の呼び出し方法
- privateなインスタンスメソッドの呼び出し方法
- privateなクラスメソッドの呼び出し方法
(2)
- privateなコンストラクタの呼び出し方法
(1)private変数やprivateメソッドへのアクセス
Hoge.java
import java.lang.reflect.Method; import java.lang.reflect.Field; public class Hoge { public static void main( String[] argv ) throws Exception { // Fugaの「クラス情報」が収められたオブジェクト Class<Fuga> c = Fuga.class; // Fugaのインスタンス Fuga fuga = new Fuga(); // 以下で,privateメンバにアクセスする。 // privateメソッド(引数なし)を呼び出して実行 Method m1 = c.getDeclaredMethod( "boo1" ); m1.setAccessible( true ); m1.invoke( fuga ); // privateメソッド(引数あり)を呼び出して実行 Method m2 = c.getDeclaredMethod( "boo2", String.class ); m2.setAccessible( true ); m2.invoke( fuga, "World" ); // privateなstaticメソッドを呼び出して実行 Method m2 = c.getDeclaredMethod( "boo3" ); m2.setAccessible( true ); m2.invoke( null ); // staticなのでインスタンスを渡す必要が無い // privateな変数を読み取り Field f1 = c.getDeclaredField( "boo_instance" ); f1.setAccessible( true ); int m = (Integer) f1.get( fuga ); System.out.println( "m = " + m ); // privateなstatic変数を読み取り Field f2 = c.getDeclaredField( "boo_static" ); f2.setAccessible( true ); int n = (Integer) f2.get( null ); // staticなのでインスタンスを渡す必要が無い System.out.println( "n = " + n ); } } // privateメンバを持つクラス class Fuga { // privateなstatic変数 private static int boo_static = 1; // privateなインスタンス変数 private int boo_instance; // 引数の無いprivateメソッド private void boo1() { System.out.println( "This is a private method." ); } // 引数のあるprivateメソッド private void boo2( String s ) { System.out.println( "Hello, " + s + "!" ); } // private なstaticメソッド private static void boo3() { System.out.println( "This is a private static method." ); } public Fuga() { // インスタンスが生成されたら, // インスタンス変数に値をセット this.boo_instance = 1; } }
コンパイルして実行
>javac Hoge.java >java Hoge This is a private method. Hello, World! This is a private static method. m = 1 n = 1
privateメソッドの呼出し手順:
- 該当クラスのClassオブジェクトを生成
- ClassからMethodオブジェクトを生成
- Methodのアクセス権限を変更
- invokeで実行
- インスタンスメソッドの場合は,インスタンスを渡す。
- クラスメソッドの場合は,nullを渡す。
private変数(フィールド)の呼出し手順:
- 該当クラスのClassオブジェクトを生成
- ClassからFieldオブジェクトを生成
- Fieldのアクセス権限を変更
- getで取得
- インスタンス変数の場合は,インスタンスを渡す。
- クラス変数の場合は,nullを渡す。
Javaリフレクションメモ:privateメンバへのアクセス
http://www.ne.jp/asahi/hishidama/home...Javaでprivateなインスタンス変数にアクセスする方法
http://aheadonestep.blogspot.com/2008...Dynamically invoking a static method without instance reference
http://www.javaworld.com/javaworld/ja...
- 静的メンバをinvokeする場合は,invokeの引数は無視される。とりあえずnullを渡せばよい。
(2)privateなコンストラクタへのアクセス
Hoge.java
import java.lang.reflect.Constructor; public class Hoge { public static void main( String[] argv ) throws Exception { // Fugaの「クラス情報」が収められたオブジェクト Class<Fuga> c = Fuga.class; // 以下で,Fugaのインスタンスを作成する。 // privateなコンストラクタを呼び出して実行 Constructor<Fuga> con = c.getDeclaredConstructor(); con.setAccessible( true ); Fuga fuga = con.newInstance(); fuga.blah(); // インスタンスメソッドを実行 } } // コンストラクタがprivateなのでインスタンスを作れないクラス class Fuga { private Fuga(){} // インスタンスメソッド public void blah() { System.out.println( "This is an instance of Fuga." ); } }
コンパイルして実行
>javac Hoge.java >java Hoge This is an instance of Fuga.
privateなコンストラクターしか持たないクラスの生成
http://oshiete.goo.ne.jp/qa/5897242.html