Java access modifiers implicitly gives access priority to packages over subclasses since the default modifier gives access to packages but not to subclasses, protected permits access to both, but there is no modifiers which permits access to subclasses but not to packages. This has always felt weird to me, because I naturally tend to consider subclasses "closer" to the parent (even because they are their own variables after all) then the classes in the same package, and often I find myself in the situation where I would like to have the modifier for sub but not for the package. This probably means I use packages in a "wrong" way, but can someone explain me the logic behind this decision?
-
Wouldn't the subclasses naturally be in the same package? – RaminS Jul 15 '16 at 17:07
-
@Gendarme just like your every swing app ends up in javax.swing package? – Coderino Javarino Jul 15 '16 at 17:08
-
@CoderinoJavarino just because someone is working on an application doesn't mean that it's a public library for external use. The OP could very well be making a private project in which the all of the subclasses would be packaged with the jar. – Matthew Smith Jul 15 '16 at 17:12
-
@CoderinoJavarino My subclass of their class is different from their own subclass. Why would they give a stranger (me) access to the class but not the classes of the same package that they developed themselves? The question seems to rather be that when you create both the super- and subclass yourself, why can you not give accessibility to the class to everyone who wishes to extend it (could be anyone), but not to the other classes of the package. – RaminS Jul 15 '16 at 17:13
-
1@ClaudioP Java access modifiers are particularly inexpressive. There's not really any point in trying to elicit the reason why they are how they are: this is how they were specified many many years ago, and we are all stuck with it if we stick with Java. 25 years of hindsight is a fantastic advantage in language design :/ – Andy Turner Jul 15 '16 at 17:23
2 Answers
When you're using the protected
modifier, you're giving unlimited access to the class. It will be possible to extend it whenever you wish to even if the class would be inappropriate for subclassing. When you use the protected
modifier, you essentially say that the class will (for the forseeable future) always be appropriate for subclassing. This might not be something that you want; for example if you have a class that is supposed to get extended a few times for a project, and no more after that.
When you have no modifier (default-access/package-private), you are giving limited access to the class. Nobody, not even you, will have access to that class outside of the package, which is something you would want if you're doing something like the above case, where the class is specific to your project and extending it for any other arbitrary project would be inappropriate. Here is a list from highest access to lowest access:
public
: Unlimited access to everyone and everythingprotected
: Unlimited access but more restrictive- default-access: Limited access to a finite amount of other classes
private
: Extremely limited access: not accessible by anything whatsoever
To have a fifth access modifier between protected
and default-access so that every class anywhere that wishes to extend it should have access to it, but not have access if they don't want to extend it is redundant, because it already exists in the form of public abstract
.

- 2,208
- 4
- 22
- 30
Applications need to be modular, that is a fact. Also, the modules need to have means to communicate with each-other. Those two usecases are what default and protected packages are for.
Usually, files related to the module you are building are in the same package. For example:
--my_module
|-- MainModuleClass
|-- HelperA
|-- HelperB
In this case, MainModuleClass
usually has fields of type HelperA
and HelperB
and the team developing the module created all 3 classes - therefore, "they know what they are doing". Also, all those 3 classes have highly related responsibilities - they make the core of your module. For those two reasons it's a great place to use "package access" as you can feel pretty safe accessing each-other class's members.
Moreover, the tests for this module are in the same package as the module itself (different directory though, but that does not matter). Therefore, the authors of the module can access the "default" access fields of the module classes to read their internal state and see if the internal behavior is correct.
Now, if some other developer decided to add some functionality by extending one of those classes, that programmer, by definition is "other" programmer. He does not know the code as well as the first team who created the original component. Therefore, some fields are marked "protected", to only give access to "outsiders" who want to extend the code and feel safe doing that.
To summarize:
- If you are building a module and want some fields to be usable only by the classes in your module - default visibility is the way to go.
- If some fields are to be extended or used by some other team who might want to reuse your module - those fields are to be protected.

- 25,562
- 10
- 53
- 84