in src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java [229:292]
private static <T extends Executable> boolean isApplicable(final T method, final Class<?>[] actuals) {
final Class<?>[] formals = method.getParameterTypes();
// if same number or args or
// there's just one more methodArg than class arg
// and the last methodArg is an array, then treat it as a vararg
if (formals.length == actuals.length) {
// this will properly match when the last methodArg
// is an array/varargs and the last class is the type of array
// (e.g. String when the method is expecting String...)
for (int i = 0; i < actuals.length; ++i) {
if (!isConvertible(formals[i], actuals[i], false)) {
// if we're on the last arg and the method expects an array
if (i == actuals.length - 1 && formals[i].isArray()) {
// check to see if the last arg is convertible
// to the array's component type
return isConvertible(formals[i], actuals[i], true);
}
return false;
}
}
return true;
}
// number of formal and actual differ, method must be vararg
if (!MethodKey.isVarArgs(method)) {
return false;
}
// fewer arguments than method parameters: vararg is null
if (formals.length > actuals.length) {
// only one parameter, the last (ie vararg) can be missing
if (formals.length - actuals.length > 1) {
return false;
}
// check that all present args match up to the method parms
for (int i = 0; i < actuals.length; ++i) {
if (!isConvertible(formals[i], actuals[i], false)) {
return false;
}
}
return true;
}
// more arguments given than the method accepts; check for varargs
if (formals.length > 0) {
// check that they all match up to the last method arg
for (int i = 0; i < formals.length - 1; ++i) {
if (!isConvertible(formals[i], actuals[i], false)) {
return false;
}
}
// check that all remaining arguments are convertible to the vararg type
// (last parm is an array since method is vararg)
final Class<?> vararg = formals[formals.length - 1].getComponentType();
for (int i = formals.length - 1; i < actuals.length; ++i) {
if (!isConvertible(vararg, actuals[i], false)) {
return false;
}
}
return true;
}
// no match
return false;
}