我如何使用Kotlin中的默认构造函数参数值实例化一个对象?
我有数据类与默认值。
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
可以为null
)。 Kotlin有没有办法达到这个目的?
Kotlin默认参数与Java反射不兼容,这意味着没有简单的方法将它们一起使用,因为Kotlin的默认参数实际上是在单独的方法下工作的,同时也传递了一个位掩码来指定哪些参数是默认参数。
有两种方法可以解决这个问题。
-
使用Kotlin反射。 例如,
callBy
函数支持默认参数,它们可以从地图中省略。 -
使用
@JvmOverloads
生成一个没有可以在Java中调用的默认参数的重载 。@JvmOverloads data class Project( val code: String, val name: String, val categories: List<String> = emptyList() )
由于您传递null而不忽略参数,因此将不会采用默认值。 https://kotlinlang.org/docs/reference/functions.html#default-arguments
您需要指定该值可以为空。 放一个?
在类型之后如果它是可以为空的,那么你可以在构造函数中检查并设置你需要的任何东西。
逃离奥古斯塔奥维达,卡拉。 Tádentro de casa programando enquanto o tempotápassando e os seusneurôniosmorrendo。 无敌!
在Kotlin中使用:
构造函数中的默认值只有当构造函数的特定参数根本没有传递给构造函数时才会被使用,这意味着它可以实现参数化构造函数的各种组合。 例如,
data class Bird (val name: String = "peacock", val gender: String = "male")
当用作Bird(),Bird(“dove”)或Bird(gender =“female”)时,默认值为。
所以要解决你的问题,你必须添加? 在类别参数旁边。 喜欢这个,
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())