Given a domain class with a parameterless constructor, how do we get a reference to that constructor through the Reflection API?
Consider for example a Student
data class, such as:
data class Student(var nr: Int = 0, var name: String? = null)
Notice, we can confirm the presence of the parameterless constructor through javap
that shows:
public pt.isel.Student(int, java.lang.String);
descriptor: (ILjava/lang/String;)V
public pt.isel.Student(int, java.lang.String, int, kotlin.jvm.internal.DefaultConstructorMarker);
descriptor: (ILjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public pt.isel.Student();
descriptor: ()V
Yet, none of the following approaches returns the parameterless constructor:
- Approach 1 -
primaryConstructor
:
val constructor = Student::class.primaryConstructor
- Approach 2 - All constructors declared in the class:
// java.util.NoSuchElementException: Collection contains no element matching the predicate
val constructor = Student::class.constructors.first { it.parameters.isEmpty() }
Alternatively, we can proceed via Java Reflection that works fine, but it should not be necessary such detour:
val constructor = Student::class.java.getDeclaredConstructor()
Second, why do we need that? Because we want to instantiate a domain class at runtime. Yes, we know that createInstance()
of KClass
do that job. But it throws IllegalArgumentException: Class should have a single no-arg constructor
if there is no parameterless constructor.
Thus, we would like to check before-hand if we could call the createInstance()
with no exceptions.