Item 15 in Effective Java states that it's recommended to use private final fields as against public final fields in an immutable object as it might prevent changing the internal representation in a later release.
I'm having trouble understanding the highlighted part - I can't see a case where changing an access specifier could cause an issue when it's already final. Could someone please provide an example for this?
It's not a matter of just changing access specifier - you might change everything about the internal representation.
Suppose you have three byte
values as part of the state of your object. You could store them in a single int
field, or you could store them in three byte
fields. If you keep the field (or fields) private, providing access to the state only, you can change your implementation later. If you use public fields, your storage detail becomes part of the API of your class, and can't be changed without breaking compatibility.
How your class stores state should be an implementation detail, hidden from the outside world for future flexibility.
(This isn't just a theoretical concern. As an example, in my Noda Time project in .NET, my v2.0 release will radically change the storage details for dates and times. If I'd made the state available as fields, that would be a large breaking change. As I've used properties instead, this change is completely transparent to users other than in terms of improved performance.)
See more on this question at Stackoverflow