Reflection problem: Order of properties/fields in (data) class


#1

Hallo,

if I have class like this:

data class ReflTest(
val zvar: Int,
val mvar: String,
val avar: Boolean
)

so:
val propList = ReflTest::class.declaredMemberProperties returns alphabeticaly sorted properties by name

0 = {KProperty1Impl@1471} "val ReflTest.avar: kotlin.Boolean"
1 = {KProperty1Impl@1472} "val ReflTest.mvar: kotlin.String"
2 = {KProperty1Impl@1473} “val ReflTest.zvar: kotlin.Int”

but val fldList = ReflTest::class.java.declaredFields returns it in natural order

0 = {Field@1470} "private final int ReflTest.zvar"
1 = {Field@1471} "private final java.lang.String ReflTest.mvar"
2 = {Field@1472} “private final boolean ReflTest.avar”

I would like to ask if there is a kotlin way to obtain class properties in natural order or if I must use declaredFields method. Thank you.

Note: kotlin v1.1.53


#2

Java does not guarantee ordering of fields. The order may be different on different JVMs.

https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredFields--

public Field[] getDeclaredFields() throws SecurityException
...
The elements in the returned array are not sorted and are not in any particular order.

#3

Thank you very much. Task was: fill the data class with data and obtain instance of it. I did it via kclazz.primaryConstructor!!.call(*constructorArgsList.toTypedArray()) - but If there is no guarantee of order so I used
kclazz.primaryConstructor!!.callBy(constructorArgsMap) and natural ordered paramaters come now from kclazz.primaryConstructor!!.parameters.


#4

I’d also love to have it

At the moment I’m using an annotation, but I have to manually type it, which is annoying and verbose

this will be awesome when you have to deal with objects/classes representing an underlaying native memory

I don’t know, maybe a keyword that will automatically trigger the metadata generation based on the declaration order?


#5

I’m not 100% sure but I think if you would use kapt to process the fields of a class you can get the fields in declaration order. You could then create some extension methods giving you the fields by index or something else depending on your need. I can’t however remember how exactly to achieve this.


#6

Found it. If you use kapt you can get a TypeElement of the class you annotate. getEnclosedElements returns all elements (fields, constructors, nested classes, methods, etc) in native (source code) order.