They wanted to be able to write framework code that could introspect Java beans and expose them directly in a user interface, amongst other things, allowing users to modify them, create them, delete them and even compose them to create their own applications... they had even imagined there could be marketplaces where you could _buy_ Java beans to add to your program, or even to modify your other beans to give them extra power... getters and setters were part of that - they needed to know how to obtain and change the state of an Object, but how the Object internally handled such state changes were up to the Object itself (what we now call encapsulation)... this was similar to how Smalltalk worked and that was an inspiration for the Java beans specification... all this never really turned out the way they wanted, of course, but have a read of the Java beans spec to get a better idea of what they had in mind if you don't fully understand it yet.
With time, people forgot completely about Java beans, but for whatever reason, getters and setters sticked around to this day. Many Java developers today think Java beans are just classes with a bunch of getters/setters and never probably heard of PropertyChangeListener, VetoableChangeListener and the other parts of the Java beans spec (some of it lives on in Swing).
If you write Java today and just want to expose some data, yeah, just go with public fields if you can't use Java 16 records yet... if you ever need to change how you internally store information, just refactor that to a setter if you really must (it will never happen).
[1] https://www.oracle.com/java/technologies/javase/javabeans-sp...
The only answer that makes any sense is this one from Brian Goetz.[1] Namely, that it's a workaround to support mutable fields of otherwise immutable objects.
To be honest, allowing you to override the methods on an immutable, auto-generated class to inject custom accessor logic feels like an immediate retreat from the conceptual goal of providing an immutable record implementation in the first place.
[1] https://stackoverflow.com/questions/66702223/why-do-java-rec...
The best explanation I have is that it is:
- a convention that seemed like a good idea for many people at the time, it even has a name: Javabeans
- it allows for a standard non magic way to add logic to be run when reading or updating fields
- in a time where source control tools and Java refactoring tools where not as developed as they are today it made sense to make getters and setters everywhere since changing from public fields to accessor methods after it were already in use was probably scary for large teams.
...Unless you're Brian Goetz's alt account?
I have a policy of saying whether if is true or false.
That said you should take his word for why it was designed that way and my word as an historical account of why I did that in 2005-2015.
I personally never had to do this so I'm not sure if this is a real benefit.
seriously, I think the reason is so you could override the getter to do something else, like compute a value and return it... but in practice this almost never happens.
Also, getters and setters don't always modify individual values. Imagine a class where we have:
private val firstName private val lastName
fun returnFullName(): return firstName + lastName
Except I'm talking about Java classes that store data. They don't do any operations on it, they don't have any internal state, they're more like C structs.
> Also, getters and setters don't always modify individual values.
Of course. But one doesn't contradict the other.
items.stream().map(Foo::bar)
vs items.stream().map(i -> i.bar)