Skip to main content
Linked to Wikipedia and other sites for further info.
Source Link

Partially, this is due to a historic accident. Strike one is that, in Java, method invocation expressions and field access expressions are syntactically different at the call site, i.e. replacing a field access by a getter or setter call breaks the API of a class. Therefore, if you might need an accessor, you must write one now, or be able to break API. This absence of language level property supportlanguage-level property support is in sharp contrast to other modern languages, most notably C#C# and EcmaScriptEcmaScript.

Strike 2 is that the JavaBeans specificationJavaBeans specification defined properties as getters/setters, fields were not properties. As a result, most early enterprise frameworks supported getters/setters, but not fields. That's long in the past by now (JPAJava Persistence API (JPA), Bean ValidationBean Validation, JAXBJava Architecture for XML Binding (JAXB), JacksonJackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

Partially, this is due to a historic accident. Strike one is that, in Java, method invocation expressions and field access expressions are syntactically different at the call site, i.e. replacing a field access by a getter or setter call breaks the API of a class. Therefore, if you might need an accessor, you must write one now, or be able to break API. This absence of language level property support is in sharp contrast to other modern languages, most notably C# and EcmaScript.

Strike 2 is that the JavaBeans specification defined properties as getters/setters, fields were not properties. As a result, most early enterprise frameworks supported getters/setters, but not fields. That's long in the past by now (JPA, Bean Validation, JAXB, Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

Partially, this is due to a historic accident. Strike one is that, in Java, method invocation expressions and field access expressions are syntactically different at the call site, i.e. replacing a field access by a getter or setter call breaks the API of a class. Therefore, if you might need an accessor, you must write one now, or be able to break API. This absence of language-level property support is in sharp contrast to other modern languages, most notably C# and EcmaScript.

Strike 2 is that the JavaBeans specification defined properties as getters/setters, fields were not properties. As a result, most early enterprise frameworks supported getters/setters, but not fields. That's long in the past by now (Java Persistence API (JPA), Bean Validation, Java Architecture for XML Binding (JAXB), Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

added 2 characters in body
Source Link
meriton
  • 4.4k
  • 19
  • 20

Strike 2 is that the JavaBeans specification defined properties as getters/setters, fieldfields were not properties. As a result, most early enterprise frameworkframeworks supported getters/setters, but not fields. That's long in the past by now (JPA, Bean Validation, JAXB, Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

Strike 2 is that the JavaBeans specification defined properties as getters/setters, field were not properties. As a result, most early enterprise framework supported getters/setters, but not fields. That's long in the past by now (JPA, Bean Validation, JAXB, Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

Strike 2 is that the JavaBeans specification defined properties as getters/setters, fields were not properties. As a result, most early enterprise frameworks supported getters/setters, but not fields. That's long in the past by now (JPA, Bean Validation, JAXB, Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

Source Link
meriton
  • 4.4k
  • 19
  • 20

Encapsulation tells me to make all or almost all fields private and expose these by getters/setters.

That is not how encapsulation is defined in object oriented programming. Encapsulation means that each object should be like a capsule, whose outer shell (the public api) protects and regulates access to its interior (the private methods and fields), and hides it from view. By hiding internals, callers to not depend on internals, allowing internals to be changed without changing (or even recompiling) callers. Also, encapsulation allows each object to enforce its own invariants, by only making safe operations available to callers.

Encapsulation is therefore a special case of information hiding, in which each object hides its internals and enforces its invariants.

Generating getters and setters for all fields is a pretty weak form of encapsulation, because the structure of the internal data is not hidden, and invariants can not be enforced. It does have the advantage that you could change the way the data is stored internally (as long as you can convert to and from the old structure) without having to change (or even recompile) callers, however.

Could somebody explain to me what is the sense of hiding all fields as private and after that to expose all of them by some extra technology? Why do we simply not use only public fields then? I feel we have walked a long and hard way only to return to the starting point.

Partially, this is due to a historic accident. Strike one is that, in Java, method invocation expressions and field access expressions are syntactically different at the call site, i.e. replacing a field access by a getter or setter call breaks the API of a class. Therefore, if you might need an accessor, you must write one now, or be able to break API. This absence of language level property support is in sharp contrast to other modern languages, most notably C# and EcmaScript.

Strike 2 is that the JavaBeans specification defined properties as getters/setters, field were not properties. As a result, most early enterprise framework supported getters/setters, but not fields. That's long in the past by now (JPA, Bean Validation, JAXB, Jackson all support fields just fine by now), but the old tutorials and books continue to linger, and not everyone is aware that things have changed. Absence of language level property support can still be a pain in some cases (for instance because JPA lazy loading of single entities does not trigger when public fields are read), but mostly public fields work just fine. To wit, my company writes all DTOs for their REST APIs with public fields (it doesn't get more public that transmitted over the internet, after all :-).

That said, Lombok's @Data does more than generate getters/setters: It also generates toString(), hashCode() and equals(Object), which can be quite valuable.

And has encapsulation really any sense now in real life programming?

Encapsulation can be invaluable or utterly useless, it depends on the object being encapsulated. Generally, the more complex the logic within the class, the greater the benefit of encapsulation.

Automatically generated getters and setters for every field are generally overused, but can be useful to work with legacy frameworks, or to use the occasional framework feature not supported for fields.

Encapsulation can be achieved with getters and command methods. Setters are not usually appropriate, because they are expected to only change a single field, while maintaining invariants may require several fields to be changed at once.

Summary

getters/setters offer rather poor encapsulation.

The prevalence of getters/setters in Java stems from a lack of language level support for properties, and questionable design choices in its historic component model that have become enshrined in many teaching materials and the programmers taught by them.

Other object oriented languages, such as EcmaScript, do support properties at the language level, so getters can be introduced without breaking API. In such languages, getters can be introduced when you actually need them, rather than ahead of time, just-in-case-you-might-need-it-one-day, which makes for a far more pleasant programming experience.