I'm a bit new with Kotlin and Java and have following question: how to check if reflected property type is ArrayList of specific type, for example is ArrayList<Pair<String, ByteArray>>?
Code behind:
class DataUploadFormData {
var files: ArrayList<Pair<String, ByteArray>> = arrayListOf()
var collection: String? = null
}
// DataUploadFormData type is passed here as T
suspend inline fun <reified T : Any> mapFormData(data: MultiPartData): T? {
val formData: FormData = getFormData(data)
val model: T? = getValue()
var fields = T::class.memberProperties
fields.forEach { field ->
if (field is KMutableProperty<*>) {
setFieldValue(field, formData, model)
}
}
return model
}
@OptIn(ExperimentalStdlibApi::class)
fun <T> setFieldValue(field: KMutableProperty<*>, formData: FormData, model: T?) {
var value: Any? = null
if (field.returnType.javaType == String::class.createType().javaType ||
field.returnType.javaType == Int::class.createType().javaType ||
field.returnType.javaType == Double::class.createType().javaType
) {
value = formData.fields.firstOrNull(predicate = { it.first == field.name })?.second
}
else if (
// check if field.returnType is of ArrayList<Pair<String, ByteArray>> type?
) {
value = formData.files
}
field.setter.call(model, value)
}
Checking simple data types works well but have no idea how to check if reflected property is of complex types. I tried to instantiate property and use is
or instanceof
but I couldn't instantiate property with code like that field.returnType.javaType::class.createInstance()
. Check field.returnType.classifier is ArrayList<*>
returns false.
Use typeOf
to get a KType
representing the type you want to check against, and use ==
to compare.
if (field.returnType == typeOf<ArrayList<Pair<String, ByteArray>>>()) {
// ...
}
You can do this for those "simple types" too.
This only checks the declared returned type of the property, not whether the property actually holds an instance of ArrayList<Pair<String, ByteArray>>
. Therefore, if the field was declared as:
var field: ArrayList<*> = arrayListOf(
"foo" to byteArrayOf()
)
The check would fail. The declared type of the field is ArrayList<*>
, but it can be said that it actually holds a ArrayList<Pair<String, ByteArray>>
.
You cannot reliably check if the type of the instance that the field holds, because of type erasure.