I have a tendency to do "public final" variables and set them in the constructor for data objects. There's this weird hangover from Smalltalk and the idea that everything should be overridable that wants getter and setters to be functions, when basically a read-only variable in an immutable data object is much simpler and just as safe.
But for some dumbass reason it's not "the Java way".
Encouraging immutable data objects is “the Kotlin way”, though.
You have explicitly mark properties as mutable (“var” instead of “val”). I didn’t get the value of this at first, but when we started catching bugs at coding tiime that would have been runtime errors in Java, I started to understand. This was among my takeaways from working with it in production for about two years.
In general Java it's still messy because although you can make the value of a variable immutable, the innards of the object it's holding are still mutable. Such as appending to a list.
You have to go as far as Clojure does and create a whole new suite of truly immutable data containers, for full safety. I dunno if Kotlin goes this far. But yeah, it's the right way.
But for some dumbass reason it's not "the Java way".