I wanted to make a class of mine Serializable (kotlinx.serialization) but realized this is not possible due to these constraints in Kotlin:
- Serializable requires every parameter in the primary constructor to be a property
- constructor properties can't have custom setters
Here's some approaches with different drawbacks marked as TODOs. For me the third option seems a bit like a workaround.
Is there any easier solution than 3. without boiler plate code?
- class is not serializable automatically because it has primary constructor parameters that are not properties
// TODO: @Serializable
class Test1(
x: Float
) {
var x: Float = x
set(value) {
field = value; b = false
}
var b: Boolean = false
fun set() {
b = true
}
}
- Can't use a custom setter on constructor property
@Serializable
class Test2(
// TODO: b is not reset everytime x is updated
var x: Float
) {
// TODO: Can't define setter for constructor property
// var x: Float = x
// set(value) {
// field = value; b = false
// }
var b: Boolean = false
fun set() {
b = true
}
}
- boiler plate code _x, using _x in code might lead to inconsistent state
@Serializable
class Test3(
@SerialName("x")
private var _x: Float
) {
var x: Float
get() = _x
set(value) {
_x = value; b = false
}
var b: Boolean = false
fun set() {
b = true
}
}
Based on your constraints, you may want to consider having two separate objects - one to serialize, and one to use in the app. The one used in the app would have your custom setters, the one to serialize would only have (val) constructor properties.
The in-app one could have a
toStorage()function (or some other name) that returns the serializable object. The serializable object could have atoState()function (or some other name) that creates the in-app-usage instance.