昨日のやりたかったことの回避策。
継承元のクラスオブジェクトからgetDeclared*メソッドで取得すりゃえんじゃねん?とか。
ボードからの帰り道で思う浮かんだんで。
こんな感じで確認。
getDeclared*メソッドで取得しても、オーバーライドしてるメソッドはサブクラスのメソッドがちゃんと動いてる。
import java.io.Serializable; import java.lang.reflect.Method; public class ReflectTest implements Serializable { private static final long serialVersionUID = -1571667747937548537L; protected void writeX() { System.out.println("ReflectTest#writeX"); } protected void writeY() { System.out.println("ReflectTest#writeY"); } public static void main(String[] args) { new ReflectTest().test(); } public void test() { try { // ReflectTestAはReflectTestを継承してる ReflectTestA testA = new ReflectTestA(); // ReflectTestBはReflectTestを継承してないけど、同じメソッドを持っている ReflectTestB testB = new ReflectTestB(); // ReflectTestクラスからwriteXメソッドを取得する Method writeXMethod = ReflectTest.class.getDeclaredMethod("writeX", (Class[]) null); // ReflectTestクラスからwriteXメソッドを取得する Method writeYMethod = ReflectTest.class.getDeclaredMethod("writeY", (Class[]) null); // ReflectTestのwriteXが呼ばれる writeXMethod.invoke(this, (Object[]) null); // ReflectTestのwriteYが呼ばれる writeYMethod.invoke(this, (Object[]) null); // ReflectTestAのwriteXが呼ばれる writeXMethod.invoke(testA, (Object[]) null); // ReflectTestのwriteYが呼ばれる(これで解決できるっぽい) writeYMethod.invoke(testA, (Object[]) null); // ReflectTestBは型が異なるため例外 writeXMethod.invoke(testB, (Object[]) null); writeYMethod.invoke(testB, (Object[]) null); } catch (Exception e) { e.printStackTrace(); } } public class ReflectTestA extends ReflectTest { private static final long serialVersionUID = 5297693222741604495L; public ReflectTestA() { super(); } protected void writeX() { System.out.println("ReflectTestA#writeX"); } } public class ReflectTestB implements Serializable { private static final long serialVersionUID = -2721698177073421574L; public ReflectTestB() { super(); } protected void writeX() { System.out.println("ReflectTestB#writeX"); } protected void writeY() { System.out.println("ReflectTestB#writeY"); } } }
コンソールには下記のように出力される。
ReflectTest#writeX ReflectTest#writeY ReflectTestA#writeX ReflectTest#writeY java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at hogehoge.ReflectTest.test(ReflectTest.java:27) at hogehoge.ReflectTest.main(ReflectTest.java:15)