code: public static boolean compatibleClasses (Class<?>[] lhs, Class<?>[] rhs)
      {
          if (lhs.length != rhs.length) {
              return false;
          }
  
          for (int i = 0; i < lhs.length; ++i) {
              if (rhs[i] == null || rhs[i].equals(Void.TYPE)) {
                  if (lhs[i].isPrimitive()) {
                      return false;
                  } else {
                      continue;
                  }
              }
  
              if (!lhs[i].isAssignableFrom(rhs[i])) {
                  Class<?> lhsPrimEquiv = primitiveEquivalentOf(lhs[i]);
                  Class<?> rhsPrimEquiv = primitiveEquivalentOf(rhs[i]);
                  if (!primitiveIsAssignableFrom(lhsPrimEquiv, rhsPrimEquiv)) {
                      return false;
                  }
              }
          }
  
          return true;
      }
docs: Tells whether instances of the classes in the 'rhs' array could be used as parameters to a
  reflective method invocation whose parameter list has types denoted by the 'lhs' array.
  
  @param lhs Class array representing the types of the formal parameters of a method.
  @param rhs Class array representing the types of the actual parameters of a method.  A null
  value or Void.TYPE is considered to match a corresponding Object or array class in lhs, but
  not a primitive.
  
  @return true if compatible, false otherwise.