From edcc559b4aabfb71a83a6cb076d5f2f4154b7277 Mon Sep 17 00:00:00 2001 From: stsypanov Date: Wed, 27 Nov 2019 14:45:16 +0200 Subject: [PATCH] Add fast-path in BeanUtils#instantiateClass For no-args constructor. See gh-24104 --- .../org/springframework/beans/BeanUtils.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index aa38a0e2ab..d11f387f27 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -51,6 +51,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.ConcurrentReferenceHashMap; +import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -188,11 +189,18 @@ public abstract class BeanUtils { try { ReflectionUtils.makeAccessible(ctor); if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) { + if (ObjectUtils.isEmpty(args)) { + return KotlinDelegate.instantiateClass(ctor); + } return KotlinDelegate.instantiateClass(ctor, args); } else { + int parameterCount = ctor.getParameterCount(); + Assert.isTrue(args.length <= parameterCount, "Can't specify more arguments than constructor parameters"); + if (parameterCount == 0) { + return ctor.newInstance(); + } Class[] parameterTypes = ctor.getParameterTypes(); - Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters"); Object[] argsWithDefaultValues = new Object[args.length]; for (int i = 0 ; i < args.length; i++) { if (args[i] == null) { @@ -887,6 +895,24 @@ public abstract class BeanUtils { return kotlinConstructor.callBy(argParameters); } + /** + * Instantiate a Kotlin class using provided no-arg constructor. + * @param ctor the constructor of the Kotlin class to instantiate + */ + public static T instantiateClass(Constructor ctor) + throws IllegalAccessException, InvocationTargetException, InstantiationException { + + KFunction kotlinConstructor = ReflectJvmMapping.getKotlinFunction(ctor); + if (kotlinConstructor == null) { + return ctor.newInstance(); + } + List parameters = kotlinConstructor.getParameters(); + Assert.isTrue(parameters.isEmpty(), "Default no-args constructor must have no params"); + Map argParameters = Collections.emptyMap(); + return kotlinConstructor.callBy(argParameters); + } + + } }