前回のメソッドの追加?では追加したメソッドから追加された側のフィールドやメソッドにアクセスできなかった。しかし、これもリフレクションを使えばできるのでは?と思い、やってみた。追加するメソッドにはObject型の引数parentが渡される。これは追加される側のオブジェクトへの参照(値)である。これはthisの代わりとして使う物である。また、privateなフィールドにアクセスするにはClass#getDeclaredField()でFieldをとってきて、Field#setAccessible()にtrueを設定する必要がある。以下ソース
import java.util.Map; import java.util.HashMap; import java.lang.reflect.Method; public class ExtensionMethod{ private Map<String, Object> objectMap; private Map<String, Method> methodMap; public ExtensionMethod(){ objectMap = new HashMap<String, Object>(); methodMap = new HashMap<String, Method>(); } public void addMethod(Object obj, String name) throws Exception{ Method method = obj.getClass().getMethod(name, Object.class); methodMap.put(name, method); objectMap.put(name, obj); } public void callMethod(String name) throws Exception{ methodMap.get(name).invoke(objectMap.get(name), this); } }
public class Parent extends ExtensionMethod{ private String fuga = "fuga"; public void print(){ System.out.println("This is Parent Message!"); } }
import java.lang.reflect.Field; public class PrintParent{ public void print(Object parent) throws Exception{ Field field = parent.getClass().getDeclaredField("fuga"); field.setAccessible(true); System.out.println(field.get(parent)); parent.getClass().getMethod("print").invoke(parent); } }
public class Main{ public static void main(String[] args) throws Exception{ Parent parent = new Parent(); PrintParent print = new PrintParent(); parent.addMethod(print, "print"); parent.callMethod("print"); } }
多少めんどうではあるが、privateフィールドとメソッドを呼び出せることでいかにも、そのオブジェクトのメソッドであるかのように振る舞うことができる。ところで、一体俺はどこに向かっているのだろう?