Java provides us with 4 different levels of access for classes and members of a class that allow us to restrict their usage from other classes.
Access modifier keywords
There are 3 keywords introduced by Java to specify the 4 access levels that we want to provide. Two of these we’ve seen in examples in previous chapters, public
and private
.
-
public
is the most permissive access level, meaning that a class or member is accessible by all other classes in our application. -
private
is the least permissive access level, meaning that a class member is only accessible by the class that contains it.
The other 2 access modifiers that Java provides are:
-
protected
meaning that a class member is only accessible by the class that contains it, subclasses of it and other classes in the same package. -
The default access level means that a class member is only accessible by the class that contains it and other classes in the same package. In contrast to
protected
, subclasses can’t access these class members.
The default access level is used when none of the other 3 modifiers are used. Hence there is no keyword associated with it. |
The following table is a good summary of what classes have visibility over classes/fields/methods with a given level of visibility.
Modifier | Owning Class | Class in Same Package | Sub-class of Owning Class | Any other class |
---|---|---|---|---|
|
Yes |
Yes |
Yes |
Yes |
|
Yes |
Yes |
Yes |
No |
default (no keyword) |
Yes |
Yes |
No |
No |
|
Yes |
No |
No |
No |
We’ll cover the concept of subclasses when we cover Inheritance later in this chapter. |
Access level modifiers for classes
Top-level classes can only be defined as public
or default access, meaning that they are either visible to all other classes in the application (public
), or only to classes in the same package (default).
Nested classes, which we haven’t covered yet, can actually have any of the 4 modifiers we defined above. Nested classes are classes defined inside other classes and will be covered in a further chapter.
Top-level classes are classes that aren’t nested, i.e., they aren’t defined inside other classes. All of the examples we’ve seen so far are of top-level classes. |
Access level modifiers for class members
As we’ve seen in previous examples, we can define access level modifiers for the fields and methods in our classes and we can use any of the 4 levels mentioned above.
Example
Let’s assume we define a Game
class with different access levels for multiple fields and methods:
package io.jcoder.tutorials.ch05.accesslevels;
public class Game {
private String title;
private int maxPlayers;
private boolean titleDefined;
public void initialize() {
title = "Unnamed Game";
maxPlayers = 0;
titleDefined = false;
}
public void setTitle(String gameTitle) {
titleDefined = true;
title = gameTitle;
}
protected void setMaxPlayers(int gameMaxPlayers) {
maxPlayers = gameMaxPlayers;
}
void printDetails() {
System.out.println("Game is: " + title + " with max players: " + maxPlayers + " - Title Set: " + titleDefined);
}
}
Our example Game
class actually defines its state as all private
(all its fields are marked as private
), and its methods with different levels of access.
As expected, the fields can be accessed from inside the Game
class even though they are marked as private
as they are owned by this class. The Game
class is allowed to read/modify their values, like we do in the initialize()
method.
Now, let’s invoke these methods from a different class. Let’s define a JavaAccessLevelApp
in our code. For the purpose of the example, make sure it is created in the same package as our Game
class above.
package io.jcoder.tutorials.ch05.accesslevels;
public class JavaAccessLevelApp {
public static void main(String[] args) {
// Our Game class is defined as public hence we can access it from all classes (including this one)
Game sampleGame = new Game();
// The initialize method is defined as public, hence we can invoke it from this class
sampleGame.initialize();
// The printDetails method is actually default level, but as this class (JavaAccessLevelApp) lives on the same
// package, we can make use of it
sampleGame.printDetails();
// The setTitle method is public so it's accessible from all classes
// The setMaxPlayers, even though it is protected, this class (JavaAccessLevelApp) lives on the same package
// so we can make use of it as well
sampleGame.setTitle("Chess");
sampleGame.setMaxPlayers(2);
// If you uncomment the lines below, you should see the compiler error and IDE suggestions about what is going
// on. These fields are not visible/accessible from this class as they are defined as private
// sampleGame.title = "Another Game Name";
// sampleGame.maxPlayers = 2;
sampleGame.printDetails();
}
}
Output:
Game is: Unnamed Game with max players: 0 - Title Set: false
Game is: Chess with max players: 2 - Title Set: true
Try uncommenting the 2 lines mentioned in the example above and see what compilation errors you get. Try also moving the JavaAccessLevelApp class into a different package. See what compilation errors you get.
|