Issue
I have a response from the server that returns me different objects and each object has a type. How I can match class in runtime with the type I get from the response? This code for example works but I am trying to get rid of the when statement and make it more dynamic.
sealed class Tile(
private val id: String,
private val type: String,
private val title: String,
) {
class RedTile(
id: String,
type: String,
title: String,
val stuff: String
) : Tile(id, type, title) {
companion object {
const val TYPE = "RedTile"
}
}
class BlueTile(
id: String,
type: String,
title: String,
val value: Int
) : Tile(id, type, title) {
companion object {
const val TYPE = "BlueTile"
}
}
companion object {
fun parseArray(jsonArrayString: String): List<Tile> {
return JsonParser.parseString(jsonArrayString).asJsonArray
.map { tileJsonObject ->
tileJsonObject as JsonObject
val tile = when (tileJsonObject.get("type").asString) {
Red.TYPE -> Red::class.java
Blue.TYPE -> Blue::class.java
else -> Red::class.java
}
Gson().fromJson(tileJsonObject, tile)
}
}
}
}
Solution
Using a static when
isn't really that bad, but I suggest moving it to a separate Tile.getTileClassByType()
function for keeping the code clean. If you prefer to search for classes dynamically, then you can use the following:
companion object {
private val tileClassesByType = Tile::class.sealedSubclasses
.associateBy { it.simpleName!! }
fun parseArray(jsonArrayString: String): List<Tile> {
...
val tile = getTileClassByType(tileJsonObject.get("type").asString) ?: RedTile::class
Gson().fromJson(tileJsonObject, tile.java)
...
}
fun getTileClassByType(type: String): KClass<out Tile>? = tileClassesByType[type]
}
Below is my original answer, before detailed information was provided in the question. It is discouraged as it is always better to avoid loading classes dynamically by name.
You can use Class.forName() from Java stdlib:
val type = tileJsonObject.get("type").asString
Class.forName("com.example.$type")
Just watch out for what you receive in this type
field. If this data is untrusted then you should validate it before using, so the other side can't instantiate objects of arbitrary classes in your application.
Answered By - broot
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.