MethodAccessImpl implements MethodAccess { @Override public Object invokeDynamic(final Object object, final Object... args) { final Class<?>[] parameterTypes = parameterTypes(); final int paramLength = method.getParameterCount(); final int argsLength = args.length; if (paramLength == 0) { return invoke(object); } if (paramLength == argsLength) { Object[] newArgs = new Object[argsLength]; for (int index = 0; index < argsLength; index++) { final Object arg = args[index]; final MethodParamAccess methodParamAccess = methodParamList.get(index); switch (methodParamAccess.typeEnum()) { case SET: if (arg instanceof Collection) { Collection<Object> argCollection = ((Collection<Object>) arg); newArgs[index] = argCollection.stream().map((Function<Object, Object>) original -> Conversions.coerce(methodParamAccess.componentType(), methodParamAccess.getComponentClass(), original)).collect(Collectors.toSet()); } break; case LIST: if (arg instanceof Collection) { Collection<Object> argCollection = ((Collection) arg); newArgs[index] = argCollection.stream().map((Function<Object, Object>) original -> Conversions.coerce(methodParamAccess.componentType(), methodParamAccess.getComponentClass(), original)).collect(Collectors.toList()); } break; case MAP: if (arg instanceof Map) { Map<Object, Object> argMap = ((Map) arg); Map<Object, Object> convertedMap = new HashMap<>(argMap.size()); argMap.forEach((oKey, oValue) -> { Object newKey = Conversions.coerce(methodParamAccess.componentKeyType(), methodParamAccess.getComponentKeyClass(), oKey); Object newValue = Conversions.coerce(methodParamAccess.componentValueType(), methodParamAccess.getComponentValueClass(), oValue); convertedMap.put(newKey, newValue); }); newArgs[index] = convertedMap; } break; case INSTANCE: newArgs[index] = Conversions.coerce(methodParamAccess.typeEnum(), methodParamAccess.getType(), arg); break; default: if (!methodParamAccess.getType().isInstance(arg)) { TypeType type = paramTypeEnumList.get(index); newArgs[index] = Conversions.coerce(type, methodParamAccess.getType(), arg); } else { newArgs[index] = arg; } } } return this.invoke(object, newArgs); } else { if (method.isVarArgs() && paramLength == 1) { return this.invoke(object, (Object) args); } else { return Invoker.invokeOverloadedFromList(object, name(), Lists.list(args)); } } } MethodAccessImpl();  MethodAccessImpl(Method method); List<List<AnnotationData>> annotationDataForParams(); Object invokeDynamicList(final Object object, List<?> args); Object invokeDynamicObject(final Object object, final Object args); @Override Object invokeDynamic(final Object object, final Object... args); Object invoke(Object object, Object... args); Object invokeBound(Object... args); @Override Object invokeStatic(Object... args); @Override MethodAccess bind(Object instance); @Override MethodHandle methodHandle(); @Override MethodAccess methodAccess(); @Override Object bound(); @Override ConstantCallSite invokeReducerLongIntReturnLongMethodHandle(T object); @Override Method method(); @Override int score(); @Override Iterable<AnnotationData> annotationData(); @Override boolean hasAnnotation(String annotationName); @Override AnnotationData annotation(String annotationName); @Override boolean isStatic(); @Override boolean isPublic(); @Override boolean isPrivate(); @Override MethodReturnAccess returnAccess(); @Override String name(); @Override Class<?> declaringType(); @Override Class<?> returnType(); @Override boolean respondsTo(Class<?>[] parametersToMatch); @Override boolean respondsTo(Object... args); @Override Class<?>[] parameterTypes(); @Override Type[] getGenericParameterTypes(); @Override String toString(); @Override boolean equals(Object o); @Override int hashCode(); @Override int compareTo(MethodAccess o2); List<TypeType> paramTypeEnumList(); @Override List<MethodParamAccess> parameters(); final public Method method; }
@Test public void testInvokeDynamic() { Map<String, Employee> map = new HashMap<>(); map.put("key", new Employee("rick")); List<Employee> employees = new ArrayList<>(); employees.add(new Employee("geoff")); Tuple<String, Employee, List> tuple = new Tuple<>(); TestService testService = new TestService(); ClassMeta classMeta = ClassMeta.classMeta(TestService.class); final MethodAccess someMethod = classMeta.method("someMethod"); Object returnValue = someMethod.invokeDynamic(testService, new Object[]{employees, map, tuple}); assertTrue((Boolean) returnValue); assertTrue(testService.someMethodCalled.get()); }