【问题标题】:How to check if a java class has a particular method in it?如何检查一个java类中是否有特定的方法?
【发布时间】:2012-06-04 05:10:06
【问题描述】:

我有一个不断变化的 xml 架构(使用 trang 自动生成)。这些变化不是很精细。此架构中仅添加或删除了一些元素。从这个模式中,我正在生成 java 类(使用 cxf),通过这些类我将解组 xml 文档。

随着架构的变化,我的自动生成的 java 类也会发生变化。同样,与模式一样,java 类的变化不是很大。例如,如果一个元素说 elemA 被添加到模式中;一些相关的函数说getElemA()setElemA()被添加到自动生成的java类中。

现在我将如何确保这些自动生成的类中存在特定的函数?一种解决方案是手写模式,以便覆盖 xml 的所有可能元素。这就是我最终要做的。但是目前我还没有固定xml文件的格式。

更新:

getElemA() 方法有可能在自动生成的类中定义。我无法控制这些类的自动生成。但是在我的主课中,如果有以下代码,

If method getElemA exists then 
     ElemA elemA = getElemA()

此代码将始终存在于我的主类中。如果在自动生成的类之一中生成方法getElemA(),则没有问题。但是如果没有生成这个方法,那么编译器就会抱怨这个方法在任何类中都不存在。

有什么方法可以让编译器在编译时不抱怨这个函数?

【问题讨论】:

    标签: java jaxb xsd


    【解决方案1】:

    @missingfaktor 提到了一种方法,下面是另一种方法(如果您知道 api 的名称和参数)。

    假设您有一种不带参数的方法:

    Method methodToFind = null;
    try {
      methodToFind = YouClassName.class.getMethod("myMethodToFind", (Class<?>[]) null);
    } catch (NoSuchMethodException | SecurityException e) {
      // Your exception handling goes here
    }
    

    如果存在就调用它:

    if(methodToFind == null) {
       // Method not found.
    } else {
       // Method found. You can invoke the method like
       methodToFind.invoke(<object_on_which_to_call_the_method>, (Object[]) null);
    }
    

    假设您有一种方法采用原生 int args:

    Method methodToFind = null;
    methodToFind = YouClassName.class.getMethod("myMethodToFind", new Class[] { int.class });
    

    如果存在就调用它:

    if(methodToFind == null) {
       // Method not found.
    } else {
       // Method found. You can invoke the method like
       methodToFind.invoke(<object_on_which_to_call_the_method>, invoke(this,
          Integer.valueOf(10)));
    }
    

    假设您有一种方法需要装箱 Integer args:

    Method methodToFind = null;
    methodToFind = YouClassName.class.getMethod("myMethodToFind", new Class[] { Integer.class });
    

    如果存在就调用它:

    if(methodToFind == null) {
       // Method not found.
    } else {
       // Method found. You can invoke the method like
       methodToFind.invoke(<object_on_which_to_call_the_method>, invoke(this,
          Integer.valueOf(10)));
    }
    

    使用上面的soln调用方法不会给你编译错误。 根据@Foumpie 更新

    【讨论】:

    • 谢谢。我想使用该方法,并且必须在该类中编写所有可能的方法,但自动生成的类可能没有该方法。如何让编译器在编译时忽略这个?
    • 使用调用不会给你编译错误...检查更新的答案。
    • 非常感谢。将其包含在try-catch 中后,它就像一个魅力。
    • 第一次调用内部使用的'invoke'即invoke(this, Integer.valueOf(10)));给我调用方法未定义的编译错误。
    • methodToFind 永远不会为 NULL,因为 NoSuchMethodException 已经被抛出。
    【解决方案2】:

    使用reflection

    import java.lang.reflect.Method;
    
    boolean hasMethod = false;
    Method[] methods = foo.getClass().getMethods();
    for (Method m : methods) {
      if (m.getName().equals(someString)) {
        hasMethod = true;
        break;
      }
    }
    

    编辑:

    因此,如果该方法存在,您希望调用该方法。这就是你的做法:

    if (m.getName().equals(someString)) {
      try {
        Object result = m.invoke(instance, argumentsArray);
        // Do whatever you want with the result.
      } catch (Exception ex) { // For simplicity's sake, I am using Exception.
                               // You should be handling all the possible exceptions
                               // separately.
        // Handle exception.
      }
    }
    

    【讨论】:

    • 感谢您的代码。主要问题是即使我已经确定方法getA 确实存在,我也需要编写该函数。例如if methodA exists then methodA()。由于此方法不退出,因此出现编译时错误。如何让编译继续进行并使其成为运行时检查?
    • @Dilawar,你应该仔细阅读一些反射教程,因为看起来你会非常需要它。
    • 我已经更新了这个问题。请看一看。你对我对反思的理解程度是对的。
    • +1 表示准确。我同意这个问题不够清楚。
    【解决方案3】:

    带弹簧:

    Method method = ReflectionUtils.findMethod(TheClass, "methodName");
    if (method != null) {
      //do what you want
    }
    

    【讨论】:

      【解决方案4】:

      如果您使用 Spring Framework,最简单的方法是使用 ReflectionUtils.findMethod() 实用程序。

      【讨论】:

        【解决方案5】:

        另一种方法是使用 Java 8 流:

          Optional<Method> methodToFind =
                        Arrays.stream(clazz.getMethods()).
                                filter(method -> "methodName".equals(method.getName())).
                                findFirst();
                if (methodToFind.isPresent()) {
                    // invoke method or any logic needed
                    ///methodToFind.get().
                }
        

        【讨论】:

          【解决方案6】:
          猜你喜欢
          • 2011-01-11
          • 1970-01-01
          • 2017-11-06
          • 2023-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-13
          • 2017-07-06
          相关资源
          最近更新 更多