is it possible to configure an object in a sealed ...
# getting-started
m
is it possible to configure an object in a sealed class to execute some behavior any time it is accessed? e.g.
Copy code
sealed class ErrorStates {
    object ThingsAreBadNow {
        onAccess {
            Logger.log("A bad thing happened")
        }
    }
}
The
init
block can be used for data classes. Is there something I can do to get a similar behavior for objects?
c
init
can be used in any class, not just data classes. Just change
object
to
class
and have its usages create new instances instead of being a singleton
m
the issue is you have to override
equals
and then
hashMap
for a stateless class in a sealed class. adds a lot of unnecessary code
c
Instead of your app doing true equality checks, doing type-checks might be better in this case. Instead of
if (error == ThingsAreBadNow)
, do
if (error is ThingsAreBadNow)
. No need to override equals/hashCode, and you get better type support with smart-casting or exhaustive
when
expressions
m
i tend to do type checks for sealed classes in general anyway. i thought it was a compiler error to have a stateless class in a sealed class, but turns out it’s just a warning
c
For most cases, it’s preferable to use an
object
for stateless subclasses since they will be always be the same, so you’d get fewer allocations. If you need to do something on accessing them, then it’s reasonable to want to create a new instance to trigger an
init
block and ignore the warning. Although, doing any logic on object-creation is generally discouraged, and you might actually be best off just having a wrapper function to protect access to the object itself.
Copy code
sealed class ErrorStates {
    private object ThingsAreBadNow : ErrorStates()

    companion object {
        fun thingsAreBadNow() : ErrorStates {
            Logger.log("A bad thing happened")
            return ThingsAreBadNow
        }
    }
}