As you may already know, there are 4 types of java visibility:
In mature and well-designed software projects, protected
and the package-default are almost never used:
In the case of protected
, the inheritance has been seen as something bad for a few years now. The reason is that inheritance introduces a strong subclass coupling to the superclass. When you use fields or methods protected
and the superclass depends on them being used in certain ways by the subclasses, you also end up coupling the superclass to your subclasses. This goes against the good practices of object-oriented system design that value the weak coupling. With the use of project standards, it is possible to eliminate all inheritance cases and exchange them for composition except when you have to use third-party libraries that cannot be modified and that provide inheritance-imposing superclasses to be used.
In the case of package-default, if a class needs to selectively expose functionalities to other classes in the same package, but not to other classes, it is a sign that there is some problem of cohesion, coupling or of encapsulation.
So, unless you’re using some library that imposes draconian restrictions on you in a well-done project, there are almost no cases where it’s a good idea to use protected
or package-default. Where they occur and are in fact the best alternative, it will probably be to circumvent some limitation of the language. So let’s focus on public
and in the private
:
In the case of fields/attributes that do not have both modifiers static
and final
, the correct modifier is the private
and period. If you are tempted to use anything other than private
in an attribute not-static
or not-final
(including forgetting to put the private
), you’re doing something wrong.
The fields that are simultaneously static
and final
may be public provided they relate to values of primitive types or immutable objects. Even when private, it is still a good idea that they are primitive values or immutable objects.
A class must publish to others, an API (set of fields, methods, constructors and internal classes) that details the functionalities it offers to the other classes to be used. The parts of the class that are in this API that it offers to others receive the modifier public
, and whatever is outside this set, should take the private
. A method that represents a complete and important functionality of class business rule should probably be public
. Something that represents a chunk of code that was in some method and that was separated in a new method just to be better organized, probably should be private
.
For methods, builders and inner classes, you have to judge whether that is something that matters to other classes or not. The class should be done by seeking to value itself by encapsulation, high cohesion and low coupling, which will help to separate what it offers to the world from what is only an internal technical detail of the way it is implemented. This judgment is subjective and requires a good deal of experience to be done correctly, but most of the time, judging which is the best case is easy, although there are always some who are in the gray zone.
Starting from Java 8, interfaces can have static methods and with standard implementations (do not confuse the modifier default
employee with visibility package-default, that is not the purpose of the modifier). This helps reduce the need to use the protected
and the package-private. Combine this with the Ambids, and this need reduces further.
Up to Java 8, everything put inside a interface
era public
, even if the keyword public
is not there (if you do not put the modifier public
in a method of a interface
, the compiler will pretend the modifier was there, there is no package-default for interface members). From Java 9, interfaces may have private methods as well (which must have the modifier private
) and that are not inherited by the classes that implement this interface. This change in Java 9 serves to eliminate one of the very few cases where visibility package-default made sense, which was to provide (through auxiliary classes in the same package) functionalities with implementations to methods default
or static
interface that should not be inherited.
You refer to the use of
private
or look for something more complex?– Leonardo Pessoa
leonardopessoa, that’s right ... I would like to know the best practices to use the access modifiers of the members of a class.
– pss1suporte
Possible duplicate of What is the difference between public, default, protected and private modifiers?
– user28595
diegofm, I believe that it is not duplicate ... because I intend to learn different ways of using .... do not compare. My question is for empirical use ... practical use, not just conceptual, you see?
– pss1suporte
@pss1good support, anyway, it is good that this gets related to the other, for research =)
– user28595
Possible duplicate of What is the difference between public, default, protected and private modifiers?
– Murillo Goulart
@diegofm, yes ... it is. Now that I have read the answers, I saw that it is good to stay related. Thank you for contributing and editing the titles. I am learning and I am learning..... Thank you!
– pss1suporte