Java反射调用getDeclaringClass

huangapple go评论174阅读模式
英文:

Java reflection invoke on getDeclaringClass

问题

我有一个像这样的接口,一些类实现了这个接口:

  1. public interface MyInterface {}
  2. public class Informations implements MyInterface {
  3. @Command("version")
  4. public void getVersion() {
  5. System.out.println("1.0-SNAPSHOT");
  6. }
  7. }
  8. public class Systems implements MyInterface {
  9. @Command("os")
  10. public void getOs() {
  11. System.out.println("Linux OS");
  12. }
  13. }

我正在收集所有带有@Command注解的方法,存储在一个Map中,就像这样:

  1. /* String is command */
  2. private Map<String, Method> commandMaps = new ConcurrentHashMap<>();

现在,我想调用这些方法:

  1. Optional<String> optionalCommand = commandMaps.keySet().stream().filter(e -> e.equals(user_input_command)).findFirst();
  2. if (optionalCommand.isPresent()) {
  3. Method method = commandMaps.get(optionalCommand.get());
  4. Class<?> declaringClass = method.getDeclaringClass();
  5. System.out.println(">> " + method.getName());
  6. System.out.println(">> " + declaringClass.getName());
  7. method.invoke(declaringClass);
  8. }

例如,用户输入了os命令,declaringClass.getName()引用了Systems类,但不能调用declaringClass。因此,这段代码会抛出IllegalArgumentException异常:

  1. >> getOs
  2. >> a.b.c.Systems
  3. java.lang.IllegalArgumentException: object is not an instance of declaring class

如何修复这个问题?

英文:

I have a interface like this and some classes implemented this interface:

  1. public interface MyInterface {}
  2. public class Informations implements MyInterface {
  3. @Command(&quot;version&quot;)
  4. public void getVersion() {
  5. System.out.println(&quot;1.0-SNAPSHOT&quot;);
  6. }
  7. }
  8. public class Systems implements MyInterface {
  9. @Command(&quot;os&quot;)
  10. public void getOs() {
  11. System.out.println(&quot;Linux OS&quot;);
  12. }
  13. }

I collecting all methods annotated @Command in a Map like this :

  1. /* String is command */
  2. private Map&lt;String, Method&gt; commandMaps = new ConcurrentHashMap&lt;&gt;();

Now , I want invoke this methods :

  1. Optional&lt;String&gt; optionalCommand = commandMaps.keySet().stream().filter(e -&gt; e.equals(user_input_command)).findFirst();
  2. if (optionalCommand.isPresent()) {
  3. Method method = commandMaps.get(optionalCommand.get());
  4. Class&lt;?&gt; declaringClass = method.getDeclaringClass();
  5. System.out.println(&quot;&gt;&gt; &quot; + method.getName());
  6. System.out.println(&quot;&gt;&gt; &quot; + declaringClass.getName());
  7. method.invoke(declaringClass);
  8. }

for example user enter os command and declaringClass.getName() referenced to Systems class but can not invoking declaringClass .
so , this code result IllegalArgumentException exception :

  1. &gt;&gt; getOs
  2. &gt;&gt; a.b.c.Systems
  3. java.lang.IllegalArgumentException: object is not an instance of declaring class

How can fix this problem ?

答案1

得分: 1

When you invoke a method via reflection, you need to pass the object you are calling the method on as the first parameter to Method#invoke.

  1. // equivalent to s1.testParam("", obj)
  2. testParamMethod.invoke(s1, "", obj);
英文:

When you invoke a method via reflection, you need to pass the object you are calling the method on as the first parameter to Method#invoke.

  1. // equivalent to s1.testParam(&quot;&quot;, obj)
  2. testParamMethod.invoke(s1, &quot;&quot;, obj);

huangapple
  • 本文由 发表于 2020年8月12日 05:04:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63366349.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定