By Mala Gupta

In this article, excerpted from OCA Java SE 8 Programmer I Certification Guide, I introduce you to the concept of default access level in Java.


The OCA Java SE 8 Programmer I exam requires that you understand the access modifiers and access levels in Java. Restricting access to a class or an interface and its members plays an important role in application design. Though Java defines three access modifiers, that is, public, protected and private, it allows four access levels-public, protected, default and private. In this article, I’ll cover how to define members with default access level and who can access them.

What happens if you don’t use an explicit access modifier, that is, public, protected or private, while defining classes, interfaces, variables or methods? Leaving out an explicit access modifier doesn’t save you from assigning an access level. A class or an interface, or members of a class defined without using any explicit access modifier are defined with package accessibility (also called default accessibility). The members with package access are only accessible to classes and interfaces defined in the same package. The default access is also referred to as package-private.

Think of a package as your home, classes as rooms, and things in rooms as variables with default access. These things aren’t limited to one room—they can be accessed across all the rooms in your home. But they’re still private to your home—you wouldn’t want them to be accessed outside your home. Similarly, when you define a package, you might want to make accessible members of classes to all the other classes across the same package.


Note While the package-private access is as valid as the other access levels, in real projects, it often appears as the result of inexperienced developers forgetting to specify the access mode of Java components.

Let’s define an instance variable issueCount and a method issueHistory with default access in class Book. Figure 1 shows the class representation with these new members.


Figure 1 Understanding class representation for default access

Here’s the code for the class:

package library;
public class Book {                  #A

    int issueCount;                   #B

    void issueHistory () {}           #C


#A Public class Book

#B Variable issueCount with default access

#C Method issueHistory with default access

You can see how classes from the same package and separate packages, derived classes, and unrelated classes access the class Book and its members (the variable issueCount and the method issueHistory) in figure 2.


Figure 2 Access of members with default access to the class Book in unrelated and derived classes from the same and separate packages

Because the classes CourseBook and Librarian are defined in the same package as the class Book, they can access the variables issueCount and issueHistory. Because the classes House and StoryBook don’t reside in the same package as the class Book, they can’t access the variables issueCount and issueHistory. The class StoryBook throws the following compilation error message: issueHistory() is not public in library.Book; cannot be accessed from outside package

Class House is unaware of the existence of issueHistory()—it fails compilation with the following error message: cannot find symbol
symbol  : method issueHistory()
location: class building.House


Defining a class Book with default access


What happens if we define a class with default access? What will happen to the accessibility of its members if the class itself has default (package) accessibility?


Consider this situation: Assume that Superfast Burgers opens a new outlet on a beautiful island and offers free meals to people from all over the world, which obviously includes inhabitants of the island. But the island is inaccessible by all means (air and water). Would the existence of this particular Superfast Burgers outlet make any sense to people who don’t inhabit the island? An illustration of this example is shown in figure 3.





Figure 3 This Superfast Burgers cannot be accessed from outside the island because the island is inaccessible by air and water.



The island is like a package in Java, and the Superfast Burgers like a class defined with default access. In the same way that the Superfast Burgers cannot be accessed from outside the island in which it exists, a class defined with default (package) access is visible and accessible only from within the package in which it is defined. It can’t be accessed from outside the package in which it resides.


Let’s redefine the class Book with default (package) access, as follows:


package library;
class Book {                     #A
    //.. class members

#A Class Book now has default access

The behavior of the class Book remains the same for the classes CourseBook and Librarian, which are defined in the same package. But the class Book can’t be accessed by classes House and StoryBook, which reside in a separate package.

Let’s start with the class House. Examine the following code:

package building;
import library.Book;                           #A

public class House {}

#A Class Book isn’t accessible in class House

The class House generates the following compilation error message: library.Book is not public in library; cannot be accessed from outside package
import library.Book;

Here’s the code of the class StoryBook:

package building;
import library.Book;                     #A
class StoryBook extends Book {}          #B

#A Book isn’t accessible in StoryBook

#B StoryBook cannot extend Book

Figure 4 shows which classes can access members of a class or interface with default (package) access.


Figure 4 The classes that can access members with default (package) access

Because a lot of programmers are confused about which members are made accessible by using the protected and default access modifiers, the following exam tip offers a simple and interesting rule to help you remember their differences.


Exam Tip Default access can be compared to package-private (accessible only within a package) and protected access can be compared to package-private + kids (“kids” refer to derived classes). Kids can access protected methods only by inheritance and not by reference (accessing members by using the dot operator on an object).