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.

Example declarations:
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:

  1. 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.

  2. 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.

  3. 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.

Here are some examples to help you identify the different declaration levels:
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

private

-

N

Y

N

package private

~

Y

Y

N

protected

protected

#

N

Y

N

public

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

  1. How many visibilities are supported by Java?

  2. How many visibility modifiers does Java have?

  3. What are the are UML symbols for each visibility supported by Java.