The access control mechanisms in Java allow us to have a more secure way of building our applications, libraries, and code in general. In this article, you’ll learn what are the access controls implemented by the Java platform, how to use them and have a better picture of how they work in general.
Access control refers to the mechanisms defined by Java to guarantee that packages, classes, etc. are accessible only to those entities which have the correct permissions and not to others which are not entitled to access them.
This sometimes can be seen as a restrictive behavior, but it’s more than that: it shields users of a class or package from depending on specific implementation details that are irrelevant to them and that could potentially break their code if such details are changed.
In short, if access to an entity is permitted, that entity is said to be accessible.
Top level class can be declared only either public
or package private, any other attempt to specify an access
modifier would result in a compilation error.
Let’s start with the most permissive one.
If a top level class or interface is declared public
,
then it may be accessed by any code declared within the same module.
On top of that, if such a class or interface is a member of a package that is exported by its module, then it’ll also be accessible by code located in another module to which the package is exported, as long as the compilation unit in which the class or interfaces is declared is visible to that other module (§6.6.1).
In contrast, if the class or interface is part of a module that’s not exported, it’ll be accessible only by code located in the same module.
When a top level class or interface is declared as "package private" it’ll be accessible only from code located within the same package.
package access is the implicit (default) access given when no modifier (public or private ) is specified.
|
A member (class, interface, field, or method) of a class, interface, type parameter, or reference type, or a constructor of a class, is accessible only if (§6.6.1):
the class, interface, type parameter, or reference type is accessible, and
the member or constructor is declared to permit access:
If the member of constructor is declared public
, then access is permitted
Otherwise, if the member or constructor is declared protected
,
then access is permitted only when:
the access occurs from within the package containing the class in which the protected member or constructor is declared
or, the code that tries to access the protected member or constructor of an object is responsible for the implementation of that object (§6.6.2).
Otherwise, if the member or constructor is declared with package access, then access is permitted only when the access occurs from within the package in which the class, interface, type parameter, or reference type is declared.
Otherwise, when the member or constructor is declared private
,
then access is permitted only when:
the access occurs from within the body of the top level class or interface that encloses the declaration of the member or constructor
or, the access occurs in the permits
clause of the top level class or interface that enclose the declaration of
the member
or, the access occurs in the record component list of the top level record class that encloses the declaration of the member
All members of interfaces lacking access modifiers are implicitly public .
|
An array type is accessible if, and only if, its element type is accessible.
When two compilation units (source files), let’s say class A
and B
are located in different modules,
let’s say moduleA
and moduleB
respectively,
if class A
is exported by moduleA
to moduleB
,
then class A
and its members and constructor(s) might be accessible to class B
,
following the previously explained rules and summarized in the
next section.
Otherwise, if class A
is not exported from moduleA
to moduleB
,
it won’t be accessible by class B
, regardless of the access modifier specified (and the next section doesn’t apply),
period.
Given we have some compilation units (source files) accessible to one another, from a module visibility point of view, then we can summarize their accessibility as follows.
In the next two tables, you can see, respectively, the different access levels for top level classes, and for members and constructor. If you’re just starting to learn or practice this content, it may be useful to keep them at hand—kind of cheat sheet. However, make sure you understand all the details and nuances previously explained and, ideally, the content from the linked resources.
Type (class, interface, etc.) | Unrelated type within the package containing the accessed type | Subtype in the same package | Subtype in a different package | Any other code that tries to access it | |
---|---|---|---|---|---|
|
|
|
|
|
|
package private |
|
|
|
Remember, we can’t declare a top level class, interface, etc. as private or protected ,
otherwise the code won’t compile.
|
Enclosing type (class/interface, etc.) | Unrelated type within the package containing the enclosing type | Subtype in the same package | Subtype in a different package | Any other code that tries to access it | |
---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
package private |
|
|
|
||
|
|