code: public static Object invokeMethod(Object object, String methodName, Object[] args)
              throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
          Class<?>[] paramTypes;
  
          if (args == null) {
              args = EMPTY_OBJECT_ARRAY;
              paramTypes = EMPTY_CLASS_PARAMETERS;
          } else {
              int arguments = args.length;
              if (arguments == 0) {
                  paramTypes = EMPTY_CLASS_PARAMETERS;
              } else {
                  paramTypes = new Class<?>[arguments];
                  for (int i = 0; i < arguments; i++) {
                      if (args[i] != null) {
                          paramTypes[i] = args[i].getClass();
                      }
                  }
              }
          }
  
          return invokeMethod(object, methodName, args, paramTypes);
      }
docs: <p>Invoke a named method whose parameter type matches the object type.</p>
  
  <p>The behaviour of this method is less deterministic
  than {@link #invokeExactMethod(Object object,String methodName,Object[] args)}.
  It loops through all methods with names that match
  and then executes the first it finds with compatible parameters.</p>
  
  <p>This method supports calls to methods taking primitive parameters
  via passing in wrapping classes. So, for example, a {@code Boolean} class
  would match a {@code boolean} primitive.</p>
  
  <p> This is a convenient wrapper for
  {@link #invokeMethod(Object object,String methodName,Object[] args,Class[] paramTypes)}.
  </p>
  
  @param object invoke method on this object
  @param methodName get method with this name
  @param args use these arguments - treat null as empty array
  @return the value returned by the invoked method
  @throws NoSuchMethodException if there is no such accessible method
  @throws InvocationTargetException wraps an exception thrown by the method invoked
  @throws IllegalAccessException if the requested method is not accessible via reflection