Merge branch '6.2.x'

This commit is contained in:
Sébastien Deleuze 2025-05-28 10:31:34 +02:00
commit a638828157
2 changed files with 54 additions and 9 deletions

View File

@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Set;
import kotlin.jvm.JvmClassMappingKt;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.reflect.KClass;
import kotlin.reflect.KFunction;
import kotlin.reflect.KParameter;
@ -659,7 +660,9 @@ public abstract class BeanUtils {
ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
@Nullable String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
Assert.state(paramNames.length == ctor.getParameterCount(),
int parameterCount = (KotlinDetector.isKotlinReflectPresent() && KotlinDelegate.hasDefaultConstructorMarker(ctor) ?
ctor.getParameterCount() - 1 : ctor.getParameterCount());
Assert.state(paramNames.length == parameterCount,
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
return paramNames;
}
@ -928,6 +931,11 @@ public abstract class BeanUtils {
}
return kotlinConstructor.callBy(argParameters);
}
public static boolean hasDefaultConstructorMarker(Constructor<?> ctor) {
int parameterCount = ctor.getParameterCount();
return parameterCount > 0 && ctor.getParameters()[parameterCount -1].getType() == DefaultConstructorMarker.class;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -93,7 +93,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate value class`() {
val constructor = BeanUtils.findPrimaryConstructor(ValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = "Hello value class!"
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ValueClass(value))
@ -102,7 +101,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate value class with multiple constructors`() {
val constructor = BeanUtils.findPrimaryConstructor(ValueClassWithMultipleConstructors::class.java)!!
assertThat(constructor).isNotNull()
val value = "Hello value class!"
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ValueClassWithMultipleConstructors(value))
@ -111,7 +109,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate class with value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(ConstructorWithValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = ValueClass("Hello value class!")
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ConstructorWithValueClass(value))
@ -120,7 +117,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate class with nullable value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(ConstructorWithNullableValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = ValueClass("Hello value class!")
var instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ConstructorWithNullableValueClass(value))
@ -131,7 +127,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate primitive value class`() {
val constructor = BeanUtils.findPrimaryConstructor(PrimitiveValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = 0
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(PrimitiveValueClass(value))
@ -140,7 +135,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate class with primitive value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(ConstructorWithPrimitiveValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = PrimitiveValueClass(0)
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ConstructorWithPrimitiveValueClass(value))
@ -149,7 +143,6 @@ class BeanUtilsKotlinTests {
@Test
fun `Instantiate class with nullable primitive value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(ConstructorWithNullablePrimitiveValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = PrimitiveValueClass(0)
var instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ConstructorWithNullablePrimitiveValueClass(value))
@ -157,6 +150,48 @@ class BeanUtilsKotlinTests {
assertThat(instance).isEqualTo(ConstructorWithNullablePrimitiveValueClass(null))
}
@Test
fun `Get parameter names with Foo`() {
val ctor = BeanUtils.findPrimaryConstructor(Foo::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).containsExactly("param1", "param2")
}
@Test
fun `Get parameter names filters out DefaultConstructorMarker with ConstructorWithValueClass`() {
val ctor = BeanUtils.findPrimaryConstructor(ConstructorWithValueClass::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).containsExactly("value")
}
@Test
fun `getParameterNames filters out DefaultConstructorMarker with ConstructorWithNullableValueClass`() {
val ctor = BeanUtils.findPrimaryConstructor(ConstructorWithNullableValueClass::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).containsExactly("value")
}
@Test
fun `getParameterNames filters out DefaultConstructorMarker with ConstructorWithPrimitiveValueClass`() {
val ctor = BeanUtils.findPrimaryConstructor(ConstructorWithPrimitiveValueClass::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).containsExactly("value")
}
@Test
fun `getParameterNames filters out DefaultConstructorMarker with ConstructorWithNullablePrimitiveValueClass`() {
val ctor = BeanUtils.findPrimaryConstructor(ConstructorWithNullablePrimitiveValueClass::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).containsExactly("value")
}
@Test
fun `getParameterNames with ClassWithZeroParameterCtor`() {
val ctor = BeanUtils.findPrimaryConstructor(ClassWithZeroParameterCtor::class.java)!!
val names = BeanUtils.getParameterNames(ctor)
assertThat(names).isEmpty()
}
class Foo(val param1: String, val param2: Int)
@ -216,4 +251,6 @@ class BeanUtilsKotlinTests {
data class ConstructorWithNullablePrimitiveValueClass(val value: PrimitiveValueClass?)
class ClassWithZeroParameterCtor()
}