简体   繁体   中英

How to check if a java class has a particular method in it?

I have an xml schema (generated automatically using trang) which keeps changing. These changes are not very elaborate. Only some elements are added or deleted from this schema. From this schema, I am generating java classes (using cxf) by which I will unmarshall the xml document.

As schema changes, my auto-generated java classes also change. Again, as with schema, changes in java classes are not very big. For instance, if an element say elemA is added to schema; some related functions say getElemA() and setElemA() are added to auto-generated java class.

Now how would I make sure that a particular function exists in these auto-generated classes? One solution is to hand-write the schema such that all possible elements of xml are covered. This is what I'll ultimately do. But for now, I have not fixed the format of xml file.

UPDATE :

There is a possibility that a method getElemA() may be defined in auto-generated classes. I do not have control over the auto-generation of these classes. But in my main class, if have following code,

If method getElemA exists then 
     ElemA elemA = getElemA()

This code will always be there in my main class. If method getElemA() is generated in one of the auto-generated class then there is no problem. But if this method is not generated then compilers complain that this method does not exists in any of the class.

Is there any way that I can make compiler not to complain about this function at compile time?

One method is mentioned by @missingfaktor and another is below (if you know the name and parameters of the api).

Say you have one method which takes no args:

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

Invoke it if present:

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

Say you have one method which takes native int args:

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

Invoke it if present:

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

Say you have one method which takes boxed Integer args:

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

Invoke it if present:

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

Using the above soln to invoke method won't give you compilation errors. Updated as per @Foumpie

Usereflection .

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

Edit:

So you want to invoke the method if it exists. This is how you do it:

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.
  }
}

With Spring:

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

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

Another way is by using Java 8 stream:

  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().
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM