Java Code Examples for java.lang.reflect.Executable#getParameterCount()

The following examples show how to use java.lang.reflect.Executable#getParameterCount() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ReflectionHelper.java    From drift with Apache License 2.0 6 votes vote down vote up
private static List<String> getParameterNames(Executable executable)
{
    requireNonNull(executable, "executable is null");

    if (executable.getParameterCount() == 0) {
        return emptyList();
    }

    // first try to get the parameter names from the ThriftField annotations
    List<Optional<String>> parameterNamesFromThriftField = Arrays.stream(executable.getParameters())
            .map(ReflectionHelper::getThriftFieldParameterName)
            .collect(toImmutableList());
    if (parameterNamesFromThriftField.stream().allMatch(Optional::isPresent)) {
        return parameterNamesFromThriftField.stream()
                .map(Optional::get)
                .collect(toImmutableList());
    }

    // otherwise get the parameter names from the class, but use any ThriftField annotations as overrides
    List<String> parameterNamesFromClass = ParameterNames.getParameterNames(executable);
    ImmutableList.Builder<String> parameterNames = ImmutableList.builder();
    for (int i = 0; i < parameterNamesFromThriftField.size(); i++) {
        parameterNames.add(parameterNamesFromThriftField.get(i).orElse(parameterNamesFromClass.get(i)));
    }
    return parameterNames.build();
}
 
Example 2
Source File: DefaultInjectorResources.java    From panda with Apache License 2.0 6 votes vote down vote up
@Override
public Collection<InjectorResourceHandler<Annotation, Object, ?>> getHandler(Parameter parameter) {
    Executable executable = parameter.getDeclaringExecutable();
    Annotation[] annotations = fetchAnnotations(parameter);

    Collection<InjectorResourceHandler<Annotation, Object, ?>> matched = new ArrayList<>(executable.getParameterCount());
    add(matched, new HandlerRecord(parameter.getType(), null));

    for (Annotation annotation : annotations) {
        add(matched, new HandlerRecord(parameter.getType(), null));
        add(matched, new HandlerRecord(parameter.getType(), annotation.annotationType()));
        add(matched, new HandlerRecord(null, annotation.annotationType()));
    }

    return matched;
}
 
Example 3
Source File: ReflectionUtil.java    From NOVA-Core with GNU Lesser General Public License v3.0 5 votes vote down vote up
static float calculateDistance(Executable exec, Class<?>[] parameterTypes) {
	float cost = 0;

	Class<?>[] execTypes = exec.getParameterTypes();
	for (int i = 0; i < exec.getParameterCount(); i++) {
		if (i >= parameterTypes.length && exec.isVarArgs())
			break;

		Class<?> a = parameterTypes[i];
		Class<?> b = execTypes[i];

		if (i == exec.getParameterCount() - 1 && exec.isVarArgs()) {
			if (isAssignmentCompatible(a, b)) {
				// Passed array for var-args.
				cost += calculateDistance(a, b);
			} else {
				cost += calculateDistance(a, b.getComponentType());
				// Penalty for every parameter that wasn't used.
				cost += (parameterTypes.length - exec.getParameterCount()) * 3F;
				// Death penalty for using var-args.
				cost += 10F;
			}
		} else {
			cost += calculateDistance(a, b);
		}
	}
	return cost;
}
 
Example 4
Source File: ReflectionUtil.java    From NOVA-Core with GNU Lesser General Public License v3.0 5 votes vote down vote up
static boolean isAssignmentCompatible(Executable exec, Class<?>... parameterTypes) {

		// First checks to eliminate an obvious mismatch.
		if (exec.isVarArgs()) {
			if (exec.getParameterCount() == 1 && parameterTypes.length == 0)
				return true;
			if (parameterTypes.length < exec.getParameterCount() - 1)
				return false;
		} else if (parameterTypes.length != exec.getParameterCount()) {
			return false;
		}

		Class<?>[] execTypes = exec.getParameterTypes();
		for (int i = 0; i < exec.getParameterCount(); i++) {

			Class<?> a = parameterTypes[i];
			Class<?> b = execTypes[i];

			if (i == exec.getParameterCount() - 1 && exec.isVarArgs()) {

				// Passed array type for var-args
				if (isAssignmentCompatible(a, b)) {
					return true;
				}

				// Var-args, have to check every element against the array type.
				b = b.getComponentType();
				for (int j = i; j < parameterTypes.length; j++) {
					a = parameterTypes[j];
					if (!isAssignmentCompatible(a, b))
						return false;
				}
				return true;
			} else if (!isAssignmentCompatible(a, b)) {
				return false;
			}
		}
		return true;
	}
 
Example 5
Source File: ExtractionUtils.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Checks whether a method/constructor can be called with the given argument classes. This includes type
 * widening and vararg. {@code null} is a wildcard.
 *
 * <p>E.g., {@code (int.class, int.class)} matches {@code f(Object...), f(int, int), f(Integer, Object)}
 * and so forth.
 */
public static boolean isInvokable(Executable executable, Class<?>... classes) {
	final int m = executable.getModifiers();
	if (!Modifier.isPublic(m)) {
		return false;
	}
	final int paramCount = executable.getParameterCount();
	final int classCount = classes.length;
	// check for enough classes for each parameter
	if (classCount < paramCount || (executable.isVarArgs() && classCount < paramCount - 1)) {
		return false;
	}
	int currentClass = 0;
	for (int currentParam = 0; currentParam < paramCount; currentParam++) {
		final Class<?> param = executable.getParameterTypes()[currentParam];
		// entire parameter matches
		if (classes[currentClass] == null || ExtractionUtils.isAssignable(classes[currentClass], param, true)) {
			currentClass++;
		}
		// last parameter is a vararg that consumes remaining classes
		else if (currentParam == paramCount - 1 && executable.isVarArgs()) {
			final Class<?> paramComponent = executable.getParameterTypes()[currentParam].getComponentType();
			while (currentClass < classCount && ExtractionUtils.isAssignable(classes[currentClass], paramComponent, true)) {
				currentClass++;
			}
		}
	}
	// check if all classes have been consumed
	return currentClass == classCount;
}
 
Example 6
Source File: ExtractionUtils.java    From flink with Apache License 2.0 5 votes vote down vote up
private static @Nullable List<String> extractExecutableNames(Executable executable) {
	final int offset;
	if (!Modifier.isStatic(executable.getModifiers())) {
		// remove "this" as first parameter
		offset = 1;
	} else {
		offset = 0;
	}
	// by default parameter names are "arg0, arg1, arg2, ..." if compiler flag is not set
	// so we need to extract them manually if possible
	List<String> parameterNames = Stream.of(executable.getParameters())
		.map(Parameter::getName)
		.collect(Collectors.toList());
	if (parameterNames.stream().allMatch(n -> n.startsWith("arg"))) {
		final ParameterExtractor extractor;
		if (executable instanceof Constructor) {
			extractor = new ParameterExtractor((Constructor<?>) executable);
		} else {
			extractor = new ParameterExtractor((Method) executable);
		}
		getClassReader(executable.getDeclaringClass()).accept(extractor, 0);

		final List<String> extractedNames = extractor.getParameterNames();
		if (extractedNames.size() == 0) {
			return null;
		}
		// remove "this" and additional local variables
		// select less names if class file has not the required information
		parameterNames = extractedNames.subList(
			offset,
			Math.min(executable.getParameterCount() + offset, extractedNames.size()));
	}

	if (parameterNames.size() != executable.getParameterCount()) {
		return null;
	}

	return parameterNames;
}
 
Example 7
Source File: MethodParameter.java    From spring-analysis-note with MIT License 4 votes vote down vote up
private static int validateIndex(Executable executable, int parameterIndex) {
	int count = executable.getParameterCount();
	Assert.isTrue(parameterIndex >= -1 && parameterIndex < count,
			() -> "Parameter index needs to be between -1 and " + (count - 1));
	return parameterIndex;
}
 
Example 8
Source File: TypeInfo.java    From smallrye-graphql with Apache License 2.0 4 votes vote down vote up
private boolean hasOneStringParameter(Executable executable) {
    return executable.getParameterCount() == 1 && CharSequence.class.isAssignableFrom(executable.getParameterTypes()[0]);
}
 
Example 9
Source File: MethodParameter.java    From java-technology-stack with MIT License 4 votes vote down vote up
private static int validateIndex(Executable executable, int parameterIndex) {
	int count = executable.getParameterCount();
	Assert.isTrue(parameterIndex >= -1 && parameterIndex < count,
			() -> "Parameter index needs to be between -1 and " + (count - 1));
	return parameterIndex;
}
 
Example 10
Source File: ReflectionPredicates.java    From raistlic-lib-commons-core with Apache License 2.0 4 votes vote down vote up
@Override
public boolean test(Executable executable) {

  return executable != null && executable.getParameterCount() == count;
}
 
Example 11
Source File: ParameterResolutionDelegate.java    From spring-analysis-note with MIT License 3 votes vote down vote up
/**
 * Due to a bug in {@code javac} on JDK versions prior to JDK 9, looking up
 * annotations directly on a {@link Parameter} will fail for inner class
 * constructors.
 * <h4>Bug in javac in JDK &lt; 9</h4>
 * <p>The parameter annotations array in the compiled byte code excludes an entry
 * for the implicit <em>enclosing instance</em> parameter for an inner class
 * constructor.
 * <h4>Workaround</h4>
 * <p>This method provides a workaround for this off-by-one error by allowing the
 * caller to access annotations on the preceding {@link Parameter} object (i.e.,
 * {@code index - 1}). If the supplied {@code index} is zero, this method returns
 * an empty {@code AnnotatedElement}.
 * <h4>WARNING</h4>
 * <p>The {@code AnnotatedElement} returned by this method should never be cast and
 * treated as a {@code Parameter} since the metadata (e.g., {@link Parameter#getName()},
 * {@link Parameter#getType()}, etc.) will not match those for the declared parameter
 * at the given index in an inner class constructor.
 * @return the supplied {@code parameter} or the <em>effective</em> {@code Parameter}
 * if the aforementioned bug is in effect
 */
private static AnnotatedElement getEffectiveAnnotatedParameter(Parameter parameter, int index) {
	Executable executable = parameter.getDeclaringExecutable();
	if (executable instanceof Constructor && ClassUtils.isInnerClass(executable.getDeclaringClass()) &&
			executable.getParameterAnnotations().length == executable.getParameterCount() - 1) {
		// Bug in javac in JDK <9: annotation array excludes enclosing instance parameter
		// for inner classes, so access it with the actual parameter index lowered by 1
		return (index == 0 ? EMPTY_ANNOTATED_ELEMENT : executable.getParameters()[index - 1]);
	}
	return parameter;
}
 
Example 12
Source File: ParameterAutowireUtils.java    From java-technology-stack with MIT License 3 votes vote down vote up
/**
 * Due to a bug in {@code javac} on JDK versions prior to JDK 9, looking up
 * annotations directly on a {@link Parameter} will fail for inner class
 * constructors.
 * <h4>Bug in javac in JDK &lt; 9</h4>
 * <p>The parameter annotations array in the compiled byte code excludes an entry
 * for the implicit <em>enclosing instance</em> parameter for an inner class
 * constructor.
 * <h4>Workaround</h4>
 * <p>This method provides a workaround for this off-by-one error by allowing the
 * caller to access annotations on the preceding {@link Parameter} object (i.e.,
 * {@code index - 1}). If the supplied {@code index} is zero, this method returns
 * an empty {@code AnnotatedElement}.
 * <h4>WARNING</h4>
 * <p>The {@code AnnotatedElement} returned by this method should never be cast and
 * treated as a {@code Parameter} since the metadata (e.g., {@link Parameter#getName()},
 * {@link Parameter#getType()}, etc.) will not match those for the declared parameter
 * at the given index in an inner class constructor.
 * @return the supplied {@code parameter} or the <em>effective</em> {@code Parameter}
 * if the aforementioned bug is in effect
 */
private static AnnotatedElement getEffectiveAnnotatedParameter(Parameter parameter, int index) {
	Executable executable = parameter.getDeclaringExecutable();
	if (executable instanceof Constructor && ClassUtils.isInnerClass(executable.getDeclaringClass()) &&
			executable.getParameterAnnotations().length == executable.getParameterCount() - 1) {
		// Bug in javac in JDK <9: annotation array excludes enclosing instance parameter
		// for inner classes, so access it with the actual parameter index lowered by 1
		return (index == 0 ? EMPTY_ANNOTATED_ELEMENT : executable.getParameters()[index - 1]);
	}
	return parameter;
}