31

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

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

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

更新 :

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

If method getElemA exists then 
     ElemA elemA = getElemA()

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

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

4

6 回答 6

49

@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参数的方法:

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参数的方法:

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)));
}

使用上述解决方案调用方法不会给您编译错误。根据@Foumpie 更新

于 2012-06-04T05:32:51.957 回答
24

使用反射

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.
  }
}
于 2012-06-04T05:21:23.767 回答
11

带弹簧:

Method method = ReflectionUtils.findMethod(TheClass, "methodName");
if (method != null) {
  //do what you want
}
于 2016-01-07T19:20:15.520 回答
4

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

于 2014-01-10T13:16:17.470 回答
2

另一种方法是使用 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().
        }
于 2020-05-10T14:07:58.113 回答