From f5ae3c77c614d0e294e4c346ba859b0fc566452d Mon Sep 17 00:00:00 2001 From: stsypanov Date: Thu, 7 Nov 2019 17:52:01 +0200 Subject: [PATCH] Use Method::getParameterCount where possible --- .../aop/framework/AopProxyUtils.java | 4 +-- .../beans/ExtendedBeanInfo.java | 5 ++- .../beans/PropertyDescriptorUtils.java | 4 +-- .../AutowiredAnnotationBeanPostProcessor.java | 11 ++++--- .../factory/support/ConstructorResolver.java | 32 +++++++++++++------ .../support/DisposableBeanAdapter.java | 6 ++-- .../InterfaceBasedMBeanInfoAssembler.java | 1 + .../core/BridgeMethodResolver.java | 5 +-- .../springframework/util/MethodInvoker.java | 4 +-- .../springframework/util/ReflectionUtils.java | 16 ++++++++-- .../ReflectiveConstructorExecutor.java | 3 +- .../ReflectiveConstructorResolver.java | 10 +++--- .../support/ReflectiveMethodExecutor.java | 3 +- .../support/ReflectiveMethodResolver.java | 10 +++--- 14 files changed, 68 insertions(+), 46 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java index a501d4614f27..e417f6ebed6b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java @@ -224,8 +224,8 @@ static Object[] adaptArgumentsIfNecessary(Method method, @Nullable Object[] argu return new Object[0]; } if (method.isVarArgs()) { - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length == arguments.length) { + if (method.getParameterCount() == arguments.length) { + Class[] paramTypes = method.getParameterTypes(); int varargIndex = paramTypes.length - 1; Class varargType = paramTypes[varargIndex]; if (varargType.isArray()) { diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java index e8952301f28f..13320a607df9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java +++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java @@ -145,11 +145,10 @@ private List findCandidateWriteMethods(MethodDescriptor[] methodDescript public static boolean isCandidateWriteMethod(Method method) { String methodName = method.getName(); - Class[] parameterTypes = method.getParameterTypes(); - int nParams = parameterTypes.length; + int nParams = method.getParameterCount(); return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) && (!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) && - (nParams == 1 || (nParams == 2 && int.class == parameterTypes[0]))); + (nParams == 1 || (nParams == 2 && int.class == method.getParameterTypes()[0]))); } private void handleCandidateWriteMethod(Method method) throws IntrospectionException { diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java index c5ac50cb4b42..9cf7acceee30 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java @@ -66,8 +66,8 @@ public static Class findPropertyType(@Nullable Method readMethod, @Nullable M Class propertyType = null; if (readMethod != null) { - Class[] params = readMethod.getParameterTypes(); - if (params.length != 0) { + int parameterCount = readMethod.getParameterCount(); + if (parameterCount != 0) { throw new IntrospectionException("Bad read method arg count: " + readMethod); } propertyType = readMethod.getReturnType(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 4b2d208a32e2..75063ba2e6b8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -696,10 +696,10 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property arguments = resolveCachedArguments(beanName); } else { - Class[] paramTypes = method.getParameterTypes(); - arguments = new Object[paramTypes.length]; - DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; - Set autowiredBeans = new LinkedHashSet<>(paramTypes.length); + int argumentCount = method.getParameterCount(); + arguments = new Object[argumentCount]; + DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount]; + Set autowiredBeans = new LinkedHashSet<>(argumentCount); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); for (int i = 0; i < arguments.length; i++) { @@ -724,8 +724,9 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property if (arguments != null) { DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length); registerDependentBeans(beanName, autowiredBeans); - if (autowiredBeans.size() == paramTypes.length) { + if (autowiredBeans.size() == argumentCount) { Iterator it = autowiredBeans.iterator(); + Class[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName) && diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 8dcfff8d3ee8..e43306b50b78 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -202,21 +202,23 @@ public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, LinkedList causes = null; for (Constructor candidate : candidates) { - Class[] paramTypes = candidate.getParameterTypes(); - if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) { + int parameterCount = candidate.getParameterCount(); + + if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) { // Already found greedy constructor that can be satisfied -> // do not look any further, there are only less greedy constructors left. break; } - if (paramTypes.length < minNrOfArgs) { + if (parameterCount < minNrOfArgs) { continue; } ArgumentsHolder argsHolder; + Class[] paramTypes = candidate.getParameterTypes(); if (resolvedValues != null) { try { - String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length); + String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); if (paramNames == null) { ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { @@ -240,7 +242,7 @@ public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, } else { // Explicit arguments given -> arguments length must match exactly. - if (paramTypes.length != explicitArgs.length) { + if (parameterCount != explicitArgs.length) { continue; } argsHolder = new ArgumentsHolder(explicitArgs); @@ -340,15 +342,24 @@ public void resolveFactoryMethodIfPossible(RootBeanDefinition mbd) { if (uniqueCandidate == null) { uniqueCandidate = candidate; } - else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParameterTypes())) { - uniqueCandidate = null; - break; + else { + boolean paramsNotMatch = isParamsNotMatch(uniqueCandidate, candidate); + if (paramsNotMatch) { + uniqueCandidate = null; + break; + } } } } mbd.factoryMethodToIntrospect = uniqueCandidate; } + private boolean isParamsNotMatch(Method uniqueCandidate, Method candidate) { + int uniqueCandidateParameterCount = uniqueCandidate.getParameterCount(); + int candidateParameterCount = candidate.getParameterCount(); + return uniqueCandidateParameterCount != candidateParameterCount || !Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParameterTypes()); + } + /** * Retrieve all candidate methods for the given class, considering * the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag. @@ -505,11 +516,12 @@ public BeanWrapper instantiateUsingFactoryMethod( LinkedList causes = null; for (Method candidate : candidates) { - Class[] paramTypes = candidate.getParameterTypes(); - if (paramTypes.length >= minNrOfArgs) { + int parameterCount = candidate.getParameterCount(); + if (parameterCount >= minNrOfArgs) { ArgumentsHolder argsHolder; + Class[] paramTypes = candidate.getParameterTypes(); if (explicitArgs != null) { // Explicit arguments given -> arguments length must match exactly. if (paramTypes.length != explicitArgs.length) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 36768418cdd8..c506958cf28f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -311,9 +311,9 @@ private Method findDestroyMethod(String name) { * assuming a "force" parameter), else logging an error. */ private void invokeCustomDestroyMethod(final Method destroyMethod) { - Class[] paramTypes = destroyMethod.getParameterTypes(); - final Object[] args = new Object[paramTypes.length]; - if (paramTypes.length == 1) { + int paramCount = destroyMethod.getParameterCount(); + final Object[] args = new Object[paramCount]; + if (paramCount == 1) { args[0] = Boolean.TRUE; } if (logger.isTraceEnabled()) { diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java index b7d3186ee81e..8248215725aa 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java @@ -231,6 +231,7 @@ private boolean isDeclaredInInterface(Method method, String beanKey) { for (Class ifc : ifaces) { for (Method ifcMethod : ifc.getMethods()) { if (ifcMethod.getName().equals(method.getName()) && + ifcMethod.getParameterCount() == method.getParameterCount() && Arrays.equals(ifcMethod.getParameterTypes(), method.getParameterTypes())) { return true; } diff --git a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java index 4061c6d98ae4..1615469dd154 100644 --- a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java +++ b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java @@ -149,10 +149,10 @@ static boolean isBridgeMethodFor(Method bridgeMethod, Method candidateMethod, Cl */ private static boolean isResolvedTypeMatch(Method genericMethod, Method candidateMethod, Class declaringClass) { Type[] genericParameters = genericMethod.getGenericParameterTypes(); - Class[] candidateParameters = candidateMethod.getParameterTypes(); - if (genericParameters.length != candidateParameters.length) { + if (genericParameters.length != candidateMethod.getParameterCount()) { return false; } + Class[] candidateParameters = candidateMethod.getParameterTypes(); for (int i = 0; i < candidateParameters.length; i++) { ResolvableType genericParameter = ResolvableType.forMethodParameter(genericMethod, i, declaringClass); Class candidateParameter = candidateParameters[i]; @@ -235,6 +235,7 @@ public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method b return true; } return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) && + bridgeMethod.getParameterCount() == bridgedMethod.getParameterCount() && Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes())); } diff --git a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java index e7b78ec5661f..8672b0197a60 100644 --- a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java +++ b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java @@ -225,8 +225,8 @@ protected Method findMatchingMethod() { for (Method candidate : candidates) { if (candidate.getName().equals(targetMethod)) { - Class[] paramTypes = candidate.getParameterTypes(); - if (paramTypes.length == argCount) { + if (candidate.getParameterCount() == argCount) { + Class[] paramTypes = candidate.getParameterTypes(); int typeDiffWeight = getTypeDifferenceWeight(paramTypes, arguments); if (typeDiffWeight < minTypeDiffWeight) { minTypeDiffWeight = typeDiffWeight; diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index eaefe0d8a44d..8f7b320d2d4b 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -240,7 +240,7 @@ public static Method findMethod(Class clazz, String name, @Nullable Class. getDeclaredMethods(searchType, false); for (Method method : methods) { if (name.equals(method.getName()) && - (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) { + (paramTypes == null || hasSameParams(method, paramTypes))) { return method; } } @@ -249,6 +249,13 @@ public static Method findMethod(Class clazz, String name, @Nullable Class. return null; } + private static boolean hasSameParams(Method method, @Nullable Class[] paramTypes) { + if (paramTypes.length != method.getParameterCount()) { + return false; + } + return Arrays.equals(paramTypes, method.getParameterTypes()); + } + /** * Invoke the specified {@link Method} against the supplied target object with no arguments. * The target object can be {@code null} when invoking a static {@link Method}. @@ -413,6 +420,7 @@ public static Method[] getUniqueDeclaredMethods(Class leafClass, @Nullable Me Method methodBeingOverriddenWithCovariantReturnType = null; for (Method existingMethod : methods) { if (method.getName().equals(existingMethod.getName()) && + method.getParameterCount() == existingMethod.getParameterCount() && Arrays.equals(method.getParameterTypes(), existingMethod.getParameterTypes())) { // Is this a covariant return type situation? if (existingMethod.getReturnType() != method.getReturnType() && @@ -504,8 +512,10 @@ public static boolean isEqualsMethod(@Nullable Method method) { if (method == null || !method.getName().equals("equals")) { return false; } - Class[] paramTypes = method.getParameterTypes(); - return (paramTypes.length == 1 && paramTypes[0] == Object.class); + if (method.getParameterCount() != 1) { + return false; + } + return method.getParameterTypes()[0] == Object.class; } /** diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java index 971297b561f6..e77eaa3ac586 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java @@ -44,8 +44,7 @@ public class ReflectiveConstructorExecutor implements ConstructorExecutor { public ReflectiveConstructorExecutor(Constructor ctor) { this.ctor = ctor; if (ctor.isVarArgs()) { - Class[] paramTypes = ctor.getParameterTypes(); - this.varargsPosition = paramTypes.length - 1; + this.varargsPosition = ctor.getParameterCount() - 1; } else { this.varargsPosition = null; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java index 82a307f6b9c2..c2de81e37897 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java @@ -69,13 +69,13 @@ public ConstructorExecutor resolve(EvaluationContext context, String typeName, L Constructor matchRequiringConversion = null; for (Constructor ctor : ctors) { - Class[] paramTypes = ctor.getParameterTypes(); - List paramDescriptors = new ArrayList<>(paramTypes.length); - for (int i = 0; i < paramTypes.length; i++) { + int paramCount = ctor.getParameterCount(); + List paramDescriptors = new ArrayList<>(paramCount); + for (int i = 0; i < paramCount; i++) { paramDescriptors.add(new TypeDescriptor(new MethodParameter(ctor, i))); } ReflectionHelper.ArgumentsMatchInfo matchInfo = null; - if (ctor.isVarArgs() && argumentTypes.size() >= paramTypes.length - 1) { + if (ctor.isVarArgs() && argumentTypes.size() >= paramCount - 1) { // *sigh* complicated // Basically.. we have to have all parameters match up until the varargs one, then the rest of what is // being provided should be @@ -84,7 +84,7 @@ public ConstructorExecutor resolve(EvaluationContext context, String typeName, L // we are supplied does match exactly (it is an array already). matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); } - else if (paramTypes.length == argumentTypes.size()) { + else if (paramCount == argumentTypes.size()) { // worth a closer look matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java index 046e63dd4ce2..2de25448b470 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java @@ -61,8 +61,7 @@ public ReflectiveMethodExecutor(Method method) { this.originalMethod = method; this.methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(method); if (method.isVarArgs()) { - Class[] paramTypes = method.getParameterTypes(); - this.varargsPosition = paramTypes.length - 1; + this.varargsPosition = method.getParameterCount() - 1; } else { this.varargsPosition = null; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java index 745cd527e562..451aee275d99 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java @@ -160,17 +160,17 @@ else if (m1.isVarArgs() && !m2.isVarArgs()) { for (Method method : methodsToIterate) { if (method.getName().equals(name)) { - Class[] paramTypes = method.getParameterTypes(); - List paramDescriptors = new ArrayList<>(paramTypes.length); - for (int i = 0; i < paramTypes.length; i++) { + int paramCount = method.getParameterCount(); + List paramDescriptors = new ArrayList<>(paramCount); + for (int i = 0; i < paramCount; i++) { paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i))); } ReflectionHelper.ArgumentsMatchInfo matchInfo = null; - if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) { + if (method.isVarArgs() && argumentTypes.size() >= (paramCount - 1)) { // *sigh* complicated matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); } - else if (paramTypes.length == argumentTypes.size()) { + else if (paramCount == argumentTypes.size()) { // Name and parameter number match, check the arguments matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); }