【问题标题】:Call a function by its name, given from string java按名称调用函数,由字符串 java 给出
【发布时间】:2010-05-31 11:01:48
【问题描述】:

我希望能够根据字符串提供的名称调用函数。类似的东西

public void callByName(String funcName){
   this.(funcName)();
}

我已经对 lambda 函数进行了一些搜索,但它们不受支持。我在考虑去Reflection,但我对编程有点陌生,所以我对这个主题不太熟悉。

当我开始 GUI(Swing、swt)编程和事件时,我的 java OOP 类提出了整个问题。我发现使用object.addActionCommand() 非常难看,因为我以后需要制作一个 Switch 并捕获我想要的确切命令。

我宁愿做object.attachFunction(btn1_click)之类的事情,这样当点击事件时它会调用btn1_click函数。

【问题讨论】:

    标签: java events reflection


    【解决方案1】:

    Java 有方法,而不是函数。不同之处在于方法有类;您需要知道调用该方法的类。如果它是一个实例方法,您需要一个实例来调用它,但 OTOH 确实意味着您可以轻松查找该方法:

    public void callByName(Object obj, String funcName) throws Exception {
        // Ignoring any possible result
        obj.getClass().getDeclaredMethod(funcName).invoke(obj);
    }
    

    请注意,有很多潜在的例外情况,如果您想传入参数,事情会变得更加复杂。

    如果你在谈论一个类方法,你所做的会略有不同:

    public void callClassByName(Class cls, String funcName) throws Exception {
        // Ignoring any possible result
        cls.getDeclaredMethod(funcName).invoke(null);
    }
    

    您可能还想使用java.lang.reflect.Proxy 进行探索。

    【讨论】:

      【解决方案2】:

      以下代码将调用给定名称的公共方法,不带参数:

      public void callByName(String funcName) {
          try {
              Method method = getClass().getDeclaredMethod(funcName);
              method.invoke(this, new Object[] {});
          } catch (SecurityException e) {
              e.printStackTrace();
          } catch (NoSuchMethodException e) {
              e.printStackTrace();
          } catch (IllegalArgumentException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (InvocationTargetException e) {
              e.printStackTrace();
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用Class.getDeclaredMethod()获取具有特定名称和参数的方法,然后调用返回的Method对象:

        Method method = MyClass.class.getDeclaredMethod("methodName", Event.class, String.class);
        Object retVal = method.invoke(someEvent, someString);
        

        【讨论】:

          【解决方案4】:

          检查 Class.forName() 以获取给定名称的类定义。

          如果您有一个包含要运行的方法的接口,并且该类实现了此方法,那么您只需创建一个实例,将其强制转换为接口并调用该方法。

          如果您不能假设任何事情,请对类的实例使用反射来获取您想要的方法,并使用所需的参数调用它。 Sun 教程中有一个很好的关于反射的部分。

          【讨论】:

            【解决方案5】:

            是的,可以使用反射 API 来执行此操作,但我认为这不是简单按钮事件处理的方法。最好询问如何在您正在使用的 GUI 框架(Swing,SWT..)中优雅地完成此操作,我确信必须有比反射更简单的方法。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-03-18
              • 2021-05-07
              • 1970-01-01
              • 2011-12-17
              • 1970-01-01
              • 2010-09-14
              相关资源
              最近更新 更多