Java apache commons MethodUtils サンプルプログラム
MethodUtilsの説明(google翻訳)
もともとコモンズBeanUtilsのメソッドに焦点を当てたユーティリティリフレクションメソッド。 BeanUtilsのバージョンとの違いは、特にLang内にすでに存在する機能が類似している場合には、注意が必要です。
既知の制限事項
デフォルトアクセススーパークラスのパブリックメソッドへのアクセス
1.4より前のJREでは、デフォルトのアクセススーパークラスに含まれるpublicメソッドを呼び出すときに問題があります。 Reflectionは、これらのメソッドを細かく見つけ、それらをpublicとして正しく割り当てます。ただし、メソッドが呼び出されると、IllegalAccessExceptionがスローされます。
MethodUtilsには、この状況の回避策が含まれています。このメソッドでAccessibleObject.setAccessible(boolean)を呼び出そうとします。この呼び出しが成功した場合、メソッドは通常どおり呼び出すことができます。この呼び出しは、アプリケーションに十分なセキュリティ特権がある場合にのみ成功します。この呼び出しが失敗した場合、メソッドは失敗する可能性があります。
Methodをクラスから取得して、実行(invoke)する。
リフレクションを行うため、アノテーションからメソッドを取得するなどの関数を持っている。
MethodUtils
package jp.pjin.tech.java; import jp.pjin.tech.java.annotation.CallTo; import jp.pjin.tech.java.domain.Iguana; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.reflect.MethodUtils; public class CommonsExample23 { public static void main(String[] args) throws Exception { Iguana obj = new Iguana(); MethodUtils.getMethodsListWithAnnotation(Iguana.class, CallTo.class).forEach(m -> { System.out.println(ReflectionToStringBuilder.toString(m, ToStringStyle.MULTI_LINE_STYLE)); try { Object result = null; if(m.getParameterTypes().length > 0){ result = MethodUtils.invokeMethod(obj, m.getName(), "桃は食べないよん。"); }else{ result = MethodUtils.invokeMethod(obj, m.getName()); } System.out.println(result); } catch (Exception e) { System.out.println(e.toString()); } }); } }
Iguana
package jp.pjin.tech.java.domain; import jp.pjin.tech.java.annotation.CallTo; public class Iguana { @CallTo public String shout() { return "うがー"; } @CallTo public void eat(String food) { System.out.println(food); } @CallTo private int walk() { return 3; } }
CallTo
package jp.pjin.tech.java.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface CallTo { }
アノテーション(CallTo)を付けた、Iguanaのメソッドを呼び出します。
MethodUtils#getMethodsListWithAnnotationでは、privateのメソッド walk がリストとして取得できなことが確認できます。
パラメータが必要な関数は、eatになります。
methodからパラメータの型配列を取得して、配列数が0よりも大きい場合は、eatになるので、パラメータを、以外はパラメータなしで実行します。
実行時には、インスタンスが必要になるので、あらかじめ作成してあります。
2つの関数が実行されるのが確認できると思います。