publicメソッドの呼び出し
前回のprivateメソッドの呼び出しのついでに、publicメソッドについて、メモ。
publicメソッドを外部からリフレクトで呼び出すなら、普通は「org.apache.commons.beanutils.MethodUtils」を使うことになるでしょう。
で、以下の2つのメソッドの違い
- MethodUtils#invokeMethod
- MethodUtils#invokeExactMethod
こんなクラスがあったとして。
public class A { public String b(String name) { return name + "さん、こんにちは。"; } }
こんなんで実行すると。(クラスAとクラスTestAは同じパッケージ)
import org.apache.commons.beanutils.MethodUtils; public class TestA { public static void main(String[] args) { try { System.out.println(MethodUtils.invokeMethod(new A(), "b", "マイケル")); } catch (Exception e) { e.printStackTrace(); } try { System.out.println(MethodUtils.invokeExactMethod(new A(), "b", "マイケル")); } catch (Exception e) { e.printStackTrace(); } } }
こんな出力結果になる。(invokeMethodもinvokeExactMethodも同じ)
マイケルさん、こんにちは。 マイケルさん、こんにちは。
Aクラスのアクセスをpublicからdefaultにすると。(public class A → class A)
class A { public String b(String name) { return name + "さん、こんにちは。"; } }
こんな出力結果になる。(invokeMethodは成功、invokeExactMethodはダメ)
マイケルさん、こんにちは。 java.lang.NoSuchMethodException: No such accessible method: b() on object: A at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:332) at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:286) at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:248) at TestA.main(TestA.java:11)
bメソッドのアクセスをpublicからdefaultにすると。(public String b → String b)
class A { String b(String name) { return name + "さん、こんにちは。"; } }
こんな出力結果になる。(invokeMethodもinvokeExactMethodもダメ)
java.lang.NoSuchMethodException: No such accessible method: b() on object: A at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:214) at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:162) at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:114) at TestA.main(TestA.java:6) java.lang.NoSuchMethodException: No such accessible method: b() on object: A at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:332) at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:286) at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:248) at TestA.main(TestA.java:11)
MethodUtils#invokeMethodのソースを見ると、内部でgetMatchingAccessibleMethodっていうメソッドを呼んでいて、クラスのアクセスを変更してました。invokeMethodとinvokeExactMethodの違いはそこだけのようです。
ということで、実行対象のメソッドを持っているクラスが、MethodUtilsクラスにとってアクセスできるかどうかの違いで使い分ける。
アクセス | invokeMethod | invokeExactMethod |
---|---|---|
MethodUtilsクラスにとってアクセスできるクラス | ○ | ○ |
MethodUtilsクラスにとってアクセスできないクラス | ○ | × |
MethodUtilsクラスにとってアクセスできないメソッド | × | × |
まー、結局、メソッド名短いし、invokeMethodを使ってりゃいいということです。