如何在Kotlin中使用默认构造函数参数值实例化对象?

时间:2017-09-15 17:55:33

标签: reflection kotlin kotlin-null-safety kotlin-reflect

我的数据类有默认值。

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

当某些值为null时,Java反射无法实例化该类。我得到了异常

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

这是因为java.lang.reflect.Constructor<T>.instantiateClass方法需要非空的参数。

我有类型信息,我有构造函数定义,但我不知道如何调用构造函数以便它使用默认值(值来自数据库,categories可以是{{ 1}})。有没有办法在Kotlin实现这个目标?

2 个答案:

答案 0 :(得分:3)

Kotlin默认参数与Java反射不兼容,这意味着没有简单的方法可以将它们一起使用,因为Kotlin默认参数实际上使用了一个单独的方法,它也通过一个位掩码来指定哪些参数是默认值。

有两种方法可以解决这个问题。

答案 1 :(得分:-2)

在Kotlin中使用

构造函数中的默认值仅在该构造函数的特定参数未传递给它时才被采用。这意味着它是为了实现参数化构造函数的各种组合而完成的。 例如,

data class Bird (val name: String = "peacock", val gender: String = "male")
当用作Bird(),Bird(&#34; dove&#34;)或Bird(性别=&#34;女性&#34;)时,

采用默认值。

那么要解决您的问题,您必须添加?在categories参数旁边。 像这样,

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

并且不需要emptyList()默认值。 当您在问题中使用emptyList时,您必须检查null并省略该参数,如此

val project = if(categories == null)
       {
          Project(code,name)
       }
       else
       {
          Project(code,name,categories)
       }

那就是在另一个kotlin类中使用这个数据类。

在JAVA中使用

但是如果你想在任何java类中使用这个数据类,那么@Hotkey说它默认不支持,因为kotlin通过使用一些方法来支持这个默认参数。

所以为了使它与java类兼容,你必须添加@JvmOverloads注释,但不能像@Hotkey所说的那样注释它必须这样注释

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