9.1. Introduction¶
Java has four different visibility options that can be used to facilitate access control, i.e., to control access to the things that we declare in our code. When you declare that something has a particular visibility in your code, you communicate to the compiler the set of locations that are allowed to access that thing.
Note
The term “access” in this context means to “use from elsewhere in the code.” With that in mind, throughout this chapter we will often say that various things are “visible from” some location; this wording just means that the thing “can be accessed from” or “can be used from” that location based on its visibility.
In Java, a declaration introduces an entity (e.g., a variable, method, class, etc.) into a program and includes an identifier (name) that can be used to represent that entity.
int x; // Variable Declaration
public class Foo // Class Declaration
public static void bar() // Method Declaration
Before we get into the specific visibility modifiers available in Java, it is important to consider a declaration’s level. In Java, entities can be declared at three different levels:
A top-level declaration is the outermost declaration in a
.java
file. Some things that can be declared at the top level include classes and interfaces.A member-level declaration is any declaration of a class or interface member. Members can include, where applicable, the constructors, methods, variables, and constants (both static or non-static/instance) of a class or interface. However, they never include local-level declarations.
A local-level declaration is any variable declaration that is local, or in scope, to a particular method. The local variables of a method include its parameter and any variables declared within the body of the method.
public class Person { // <------------ `Person` is top-level
private String name; // <---------- `name` is member-level
public Person(String name) { // <-- `Person` is member-level; `name` is local-level
int x = 42; // <---------------- `x` is local-level
this.name = name; // <---------- not a declaration
} // Person
} // Person
The table below shows all four visibility options that are available in Java, three of which have an associated visibility modifier that we can include in various declarations throughout our code. The set of potential visibility options for a declaration may also depend on its level and other factors.
Visibility Name |
Modifier Keyword |
UML Symbol |
Top-Level |
Member-Level |
Local-Level |
---|---|---|---|---|---|
private |
|
|
N |
Y |
N |
package private |
|
Y |
Y |
N |
|
protected |
|
|
N |
Y |
N |
public |
|
|
Y |
Y |
N |
In this tutorial, we cover each available visibility option with a few examples, often illustrated using a combination of UML diagrams and code snippets.
We will take some liberties when discussing examples involving multiple
labeled lines (e.g., LINE1
) of code; for example, whenever we consider
whether or not a line will work, we will make a good-faith assumption that
all other labeled lines of code will also work, even if we find out later
that they don’t. We mention this because, technically if one does not work,
then the whole thing might not work; however, at the same time, it’s usually
less constructive to break such an example into multiple examples as that
impacts readability.
Test Yourself
How many visibilities are supported by Java?
How many visibility modifiers does Java have?
What are the are UML symbols for each visibility supported by Java.