回答編集履歴

1 リファイン

argius

argius score 9526

2015/07/01 15:36  投稿

実行時に存在するかどうかわからないクラスやメソッドを実行するには、 **リフレクション**を使用します。
実行時に存在するかどうかわからないクラスやメソッドを実行するには、 **リフレクション** を使用します。
正確には、ソースがあるかどうかではなく、クラスがクラスパスに設定されているかどうか、です。
 
※以下のソースではどんな例外がスローされるかが分かるように個別に`catch`ブロックを設けていますが、必要が無ければ分けなくてもOKです。  
- Hoge.java
```lang-java
package local;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Hoge {
   public static void main(String[] args) {
       Class<?> c;
       try {
           c = Class.forName("local.Huga");
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
           return;
       }
       Object o;
       try {
           o = c.newInstance();
       } catch (InstantiationException|IllegalAccessException e) {
       } catch (InstantiationException | IllegalAccessException e) {
           e.printStackTrace();
           return;
       }
       Method m;
       try {
           m = c.getDeclaredMethod("hage", int.class);
       } catch (NoSuchMethodException |SecurityException e) {
       } catch (NoSuchMethodException | SecurityException e) {
           e.printStackTrace();
           return;
       }
       try {
           m.invoke(o, 3); // => Huga.hage(), arg=3
       } catch (IllegalAccessException |IllegalArgumentException |InvocationTargetException e) {
       } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
           e.printStackTrace();
           return;  
       }
   }
}
```
- Huga.java
```lang-java
package local;
public class Huga {
   public void hage(int arg) {
       System.out.println("Huga.hage(), arg=" + arg);
   }
}
```
リフレクションを使う場合は、直接操作するよりも、インターフェイスを介して行う方が推奨されています。
```lang-java
package local;
public interface IHuga {
public interface IHuga { // Hugaクラスは これを implements する
   public void hage(int i);
}
```
```lang-java
IHuga o;
try {
   o = (IHuga)Class.forName("local.Huga").newInstance(); // ここだけ例外をチェックすれば良い
   o.hage(3);
} catch (InstantiationException |IllegalAccessException |ClassNotFoundException e) {
   o = (IHuga)Class.forName("local.Huga").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
   e.printStackTrace();
   return;  
}
```
o.hage(3); // インターフェイスを介しての実行時にはリフレクションのエラーは発生しない
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る