Can I create a data class at run-time?

#1

Hello,

Can I create a totally new Kotlin (data) class type at run-time, dynamically ?
By this I mean that I want to create a totally new type dynamically, I am not asking about creating a new instance of a known type.

Basically I want to do at run-time what Kotlin compiler does at compile-time for serializable data classes.

Example of a serializable data class I want to create:

@Serializable
data class MyData( val f1: String, val f2: Boolean)

The reason I wanted to do this is so that I can create these data classes which will be used to serialize and de-serialize to/from Json (using Kotlinx Json library).
Right now there is IDEA plug-in which does it statically inside editor IDE, i.e. generating boiler-plate code. This approach/plug-in works well but it is static in nature.
Having an option of creating new data class types at run-time may be even better (?).

thank you

#2

You can’t create any class in runtime. You can use dynamic structures like maps or JsonObject to store dynamically created data.

In fact, there are ways in JVM involving runtime use of compiler or bytecode weather, but you should never use it.

1 Like
#3

Funny. Actually you CAN. For example, you can generate&run kotlin script|java script|python etc from your ‘native’ code and in it you can define new type and produce its instances. But what will you do with those instances out of this script? Every type in your ‘native’ code must be resolved in compile-time, for casting you also use resolved types. Even using reflection you manipulate already resolved types.

Standard way to map dynamic (badly engeneered) json|xml api payload is to build hierarchical structure. For example JsonObject tree which is from-the-box solution in jdk. Or you can use one of mapping solutions like Gson|Jackson. They gives you “adapters” for serializing|deserializing specified nodes to minify brain damage from case-sensitive node types. For example i have “status” field in server payload which can be array or integer. I define status array in my target type and use adapter which read integer or array from json field and produces array always. If you have more complex case you can use abstract class|interface and produce it’s children for different node types.

When you have already known static typed json payload - you just define your dataclass and produce it’s instance from payload using Gson|Jackson. And yes, you can’t work with dynamic types in static typed languages. Actually you can’t work with dynamic types in dynamic typed languages - they just decorate hierarchical structures which consist of primitive types for you. But it’s another story.

1 Like
#4

There is no straightforward case where dynamically generating serialized classes actually has benefits. In case you need specific class details you need things to be statically available. In case you don’t care about content, you don’t need the serialization framework (just the parser or generic structures such as JsonObject).