Java Encapsulation

Encapsulation facilitates control over access to components of a class. Read this article to get a clear understanding.


Encapsulation is an important feature of Java that allows a programmer to control access to components of a class. Used properly, encapsulation can enhance program security. Used improperly, encapsulation can create major security risks in a program.



Object-oriented programming languages such as Java include features that support the object-oriented programming paradigm. These features include data abstraction, encapsulation, information hiding, polymorphism, and inheritance. Encapsulation refers to the bundling of both data and methods (behaviors) into a single entity called a class, which can be easily incorporated into different programs. A class defined in a Java program is used to declare objects of that class type. Using the feature of encapsulation, the programmer can restrict access to components of the class, which is a key strength of encapsulation in Java. Java classifies class members (data members and member methods) into one of three categories using access specifiers, which are also reserved words: private, public, and protected. Access specifiers determine the visibility or accessibility of an object's members, as specified in the table below:

Types of Threat Accesibility
Private Accessible only by member methods of the class or by friends of the class
Public Accessible by methods both inside and outside of the class
Protected Accessible by member methods of the class, by friends of the class, and by member methods of any subclass

In Java, the access specifier is included in each of the class's variable and method declarations, preceding the data type. Be careful! When no modifier is given, the default access specifier is public, meaning that methods in any class within the same package, or one that imports that package, will be able to use, access, or modify these members.

An example of a Java class declaration follows:

public class Time {
private int hour; private int minute; private int second;
public Time()
    { /* constructor implementation */ }
public void setTime(int newHour, int newMinute, int newSecond)
    { /* mutator implementation */ }
public int[] getTime()
    { /* accessor implementation */ }
public void incrementTime()
    { /* mutator implementation */ }

In the example above, the data members hour, minute, and second and the member methods setTime(), getTime() and incrementTime() are bundled into a single autonomous class named Time. This demonstrates the encapsulation feature of Java. When all data is declared as private, the data is only accessible through the methods provided by the class. This restricted access is illustrated below.

Such restricted access requires programmers to write specialized accessor methods like getTime() for acquiring the values of private data members and specialized mutator methods like setTime() and incrementTime() for performing operations on them. This allows programmers to validate changes to data members before making such a change. In this example, the setTime() method would be written to check for valid values for military time (hour is between 0 and 23 and minute and second are between 0 and 59.)

Encapsulation hides the private data members and the implementation details of a class, but it does not necessarily mean a class is completely isolated. Many objects must share information with other objects, usually with good reason. However, protecting private data by providing accessor and mutator methods ensures that an object is affected only in known ways by other objects in the system. Sharing should be minimized so that the class provides as few interfaces (public methods) as possible. Other methods required for the class should be private, so they are not available outside the class.

Using encapsulation properly and providing a controlled public interface is similar to a fast-food restaurant that has no indoor customer access and provides only a drive-up window. The customer can read the menu, place an order from the menu, pay for the order, and pick up the completed order. The customer does not know exactly what is occurring inside the restaurant; he or she knows only that placing an order and paying for it results in the food showing up in the completed order. The customer may return to the same fast-food restaurant every day for a month and interact with the restaurant in the same way. If the restaurant hires a consultant to cut costs and changes the way orders are filled, the customer has no knowledge of the change, and does not really need to know about it. As long as the customer interacts with the restaurant in the same way and the food tastes just as good each time, the customer does not really even care about the internal operations of the restaurant.

Proper use of encapsulation in Java enhances program security for several reasons:

  1. The initial value of all data members is controlled by the programmer writing the code for the class.
  2. Access to an object's data is controlled by the programmer writing the code for the class, resulting in fewer human errors caused by improper use of the class by other programmers. Encapsulated objects that declare data as private or protected act as a black box, protecting the object's data and allowing access to the data only by calling class member methods, which control how the data can be accessed and/or changed. Data is secure because it can only be accessed in a safe manner, in the same way that a bank account is secure because it can only be accessed in a safe manner.
  3. Encapsulated objects provide full functionality; however, calling objects do not know the implementation details, and cannot rely on or take advantage of a particular implementation. This means that the implementation can be enhanced or updated in the future without affecting calling objects. 4. If a class is isolated from the effects of other classes in the program using encapsulation, it is easier to trace a fault to the class that caused it and to limit the damage caused by the fault.


Risk - How Can It Happen?

If a programmer does not use encapsulation properly, the existence of the encapsulation feature in Java provides no enhanced security. In fact, using encapsulation improperly can greatly increase the insecurity of the program. Encapsulation violations increase program insecurities in direct proportion to how much intelligence the class contains. If the class stores one simple data element, such as a char, whose value can be any legal char value, then encapsulation violations are probably not a big issue. As the data becomes more complicated, encapsulation violations create more and more insecurities, since the special properties of the data (such as limiting hour to values between 0 and 23, inclusive) are more and more likely to be violated.

As the rules of proper encapsulation are violated, all clients of the class become responsible for more and more code to correctly access and use the object's data. As the class is enhanced and updated over time, it is not possible to correct all uses of the class, particularly if external users are out of the programmer's control. Eventually the class loses integrity entirely and becomes a security vulnerability.


Example in Code:

Consider the following class declaration:

public class RiskyTime {
    int hour;
    int minute;
    int second;
    void setTime(int newHour, int newMinute, int newSecond)
        { /* mutator implementation */ }
    int[] getTime()
        { /* accessor implementation */ }
    void incrementTime()
        { /* mutator implementation */ }

The RiskyTime class has no modesty; its data is hanging out in public for the entire program to see. The reason this is an issue for a class is the same reason it is a personal issue. When a person is exposed, he or she may get sunburned in all the wrong places. When data is exposed, other components have complete access to that data and can cause mischief. Since RiskyTime allows all methods in the entire program direct access to its data members, an external method could set hour, minute, and second to an invalid time, such as 36:99:-33 (hour:minute:second). Clients that use the class cannot count on the time being valid. If the client uses the class, anyway, and does not check to be sure the object's data is valid every time it is used, the invalid values can cause strange, and even dangerous, things to occur when the program executes.


Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.

Last modified: Monday, April 15, 2019, 7:56 PM