code: public static boolean isVoidMethod(@Nullable Object target, String method, Object... args) {
      if (target == null) return false; // no way to tell
  
      Class[] argTypes = ReflectionUtil.getTypes(args);
  
      // the way we choose metaClass, we won't find methods on java.lang.Class
      // but since java.lang.Class has no void methods other than the ones inherited
      // from java.lang.Object, and since we operate on a best effort basis, that's OK
      // also we will choose a static method like Foo.getName() over the equally
      // named method on java.lang.Class, but this is consistent with current Groovy semantics
      // (see http://jira.codehaus.org/browse/GROOVY-3548)
      // in the end it's probably best to rely on NullAwareInvokeMethodSpec to tell us if
      // everything is OK
      MetaClass metaClass = target instanceof Class ?
          InvokerHelper.getMetaClass((Class) target) : InvokerHelper.getMetaClass(target);
  
      // seems to find more methods than getMetaMethod()
      MetaMethod metaMethod = metaClass.pickMethod(method, argTypes);
      if (metaMethod == null) return false; // we were unable to figure out which method was called
  
      Class returnType = metaMethod.getReturnType();
      // although Void.class will occur rarely, it makes sense to handle
      // it in the same way as void.class
      return returnType == void.class || returnType == Void.class;
    }
docs: InvokerHelper.invokeMethod, even if the same method is chosen (see Spec GroovyMopExploration)