Classes and class members (classes, interfaces, fields, and methods) are access controlled in Java. The access is indicated by an access modifier (public, protected, or private) or by the absence of an access modifier (the default access, also called package-private access).
The following table presents a simplified view of the access control rules. An x indicates that the particular access is permitted from within that domain. For example, an x in the class column means that the member is accessible to code present within the same class in which it is declared. Similarly, the package column indicates that the member is accessible from any class (or subclass) defined in the same package, provided that the class (or subclass) is loaded by the class loader that loaded the class containing the member. The same class loader condition applies only to package-private member access.
access specifierAccess Specifier | classClass | packagePackage | subclassSubclass | worldWorld |
|---|---|---|---|---|
| x |
|
|
|
noneNone | x | x | x* |
|
| x | x | x** |
|
| x | x | x | x |
...
Protected accessibility is invalid for top-level classes; nested classes may be declared protected. Fields of nonfinal public classes should rarely be declared protected; untrusted code in another package can subclass the class and access the member. Furthermore, protected members are part of the API of the class and consequently require continued support. When this rule is followed, there is no need to declare a field as protected. OBJ01-J. Declare data members as private and provide accessible wrapper methods recommends declaring fields as private.
If a class, interface, method, or field is part of a published API, such as a web service end pointendpoint, it may be declared public. Other classes and members should be declared either package-private or private. For example, non-security-critical classes are encouraged to provide public static factories to implement instance control with a private constructor.
...
This compliant solution declares the Point class as package-private in accordance with its status as not part of any public API.:
| Code Block | ||
|---|---|---|
| ||
final class Point {
private final int x;
private final int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
public void getPoint() {
System.out.println("(" + x + "," + y + ")");
}
}
|
A top-level class, such as Point, cannot be declared private. Package-private accessibility is admissible , provided package insertion attacks are avoided. (See ENV01-J. Place all security-sensitive code in a single JAR and sign and seal it.) A package insertion attack occurs when, at runtime, any protected or package-private members of a class can be called directly by a class that is maliciously inserted into the same package. However, this attack is difficult to carry out in practice because, in addition to the requirement of infiltrating into the package, the target and the untrusted class must be loaded by the same class loader. Untrusted code is typically deprived of such levels of access.
Because the class is final, the getPoint() method can be declared public. (A public subclass that violates this rule cannot override the method and expose it to untrusted code, so its accessibility is irrelevant.) . For nonfinal classes, reducing the accessibility of methods to private or package-private eliminates this threat.
...
Related Guidelines
Bibliography
Item 13: , "Minimize the accessibility Accessibility of classes and members; Classes and Members" | |
[JLS 2011] | |
Chapter 3, "Java Language Security Constructs" |
...