Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I instantiate an object using default constructor parameter values in Kotlin?

I have data class with default values.

data class Project(
    val code: String,
    val name: String,
    val categories: List<String> = emptyList())

Java reflection fails to instantiate the class when some values are null. I'm getting exception

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method Project.<init>, parameter categories

This is because java.lang.reflect.Constructor<T>.instantiateClass method expects arguments that are not null.

I have the type information, I have the constructor definition but I'm not sure how to call the constructor so that it uses the default values (The values are coming from the database and categories can be null). Is there any way to achieve this in Kotlin?

like image 567
rosencreuz Avatar asked Sep 15 '17 17:09

rosencreuz


People also ask

How do you use a constructor parameter in Kotlin?

The primary constructor is initialized in the class header, goes after the class name, using the constructor keyword. The parameters are optional in the primary constructor. The constructor keyword can be omitted if there is no annotations or access modifiers specified.

How do you make a default constructor in Kotlin?

We can use a primary constructor of the superclass. Note that all classes in Kotlin are final by default. This means we'll need to add the open keyword so that we can inherit from our Person class. By doing this, we pass a name to the primary constructor of Person class.


1 Answers

The Kotlin default parameters are not compatible with Java reflection, meaning there's no simple way to use them together, because the Kotlin default parameters actually work with a separate method under the hood that is also passed a bit mask to specify which arguments are default.

There are two ways to fix this.

  • Use Kotlin reflection. For example, the callBy function supports default parameters, they can be omitted from the map.

  • Use @JvmOverloads to generate an overload without the default parameterwhich can be called in Java.

    @JvmOverloads
    data class Project(
        val code: String,
        val name: String,
        val categories: List<String> = emptyList()
    )
    
like image 200
hotkey Avatar answered Sep 21 '22 17:09

hotkey