effective java has a statement about the access control: Even if a field is final and refers to an immutable object, by making it public you give up the flexibility to switch to a new internal data representation in which the field does not exist.
I don't understand what it means. Appreciate if someone can explain.
Unlike newer languages like Kotlin and Scala, Java makes a very clear distinction between fields and methods. So if you've got a
Then that's always pointing to an actual field in memory. It can never be a method, and it can never run arbitrary code. The call
myInstance.foo
is always direct memory access, which is contrary to OOP principles. When I ask an instance for something, it should be the instance's decision how to handle that request, not mine.In Kotlin, properties can have getters and setters, so even if we have something that looks like a field, it might call a method to access it. This allows us to future-proof our code in advance. We can implement an actual instance variable now,
and then, down the road, when
foo
needs to go make a database query or something because we're scaling our application up, we can change the implementationCrucially, this affects nobody downstream. Everybody else downstream still writes
myInstance.foo
and works with the new code. It's not a breaking change.We can't do this in Java.
myInstance.foo
is always a variable, not a method. So Effective Java suggests always accessing instance variables through a method in order to future-proof them. If we writeThen we can change
getFoo
in the future without breaking other code. It's a difference in philosophy: In Java, methods are the OOP construct while instance variables are strictly an implementation detail. In most newer languages, "instance variable" has been replaced with a high-level construct called a "property" which is intended to be used in an OOP way.