Encapsulation is the process by which data is combined into a single unit and can't be accessed by unauthorized code or users. Think of encapsulation as being like a sack of chips at the grocery store. You can look at the sack of chips, but until you pay for it, you're not authorized to open it to eat the individual chips inside.
Protecting computer data is an ongoing issue. After all, there's some information you must be willing to share such as your medical records at a doctor's office. You never want this information, of course, to be hacked by outside entities. Even within a company or organization, though, you also want the fewest number of people – only those who need to know – to have access to this data.
So, what exactly is data encapsulation in Java? How does it work, and when should you use it? We'll go over the basics below so you can protect your data as well as possible.
What is Data Encapsulation in Java?

Data encapsulation is an object-oriented programming (OOP) concept designed to protect data. This is done by combining the variables (data) and code (methods) into one package. After encapsulation, all variables will be inaccessible unless using methods associated with that class. This process is also known as data hiding.
Performing data encapsulation is a three-step process:
- Set class variables as private.
- Define the getter method which retrieves variable data to be read.
- Define the setter method which allows data to be changed or not.
There are a variety of benefits achieved through encapsulation:
- Flexibility: Class variables can be easily set to read-only or write-only. Plus, you can limit the types of data which can be entered in a field. You can also trigger events when data is modified.
- Data hiding: Users will not be able to access variable data unless using the predefined getter method.
- Maintain data: Encapsulated application code is segmented into discrete units – setters, getters, methods, classes, and so on – which means you can work with a single unit without affecting the performance of others.
- Reuse data: Encapsulated data can be reused at multiple points in the application programming interface (API) or even across multiple APIs.
Using Data Encapsulation in Java
As noted above, data encapsulation is a three-step process. First, you'll set class variables as private. Second, you'll define the getter methods to access this variable data. Finally, defined setter methods will determine if this data can be changed.
For example, let's look at this sample data encapsulation code below:
public class SampleEncap {
private String idNumber;
private String name;
private int age;
public String getIdNumber() {
return idNumber;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setIdNumber(String newIdNumber) {
idNumber = newIdNumber;
}
public void setName(String newName) {
name = newName;
}
public void setIdAge(int newAge) {
newAge = newAge;
}
}
As you'll see by looking at the code above, it has three sections:
- variable data idNum, Name, and age are set to private
- getter rules allow the data to be viewed
- setter rules make this read-only data
Checking Data Encapsulation
Once you've set up your data encapsulation methods, you need to check the code to make sure it's executing correctly. First, input variable data to be checked, and then, generate output as per this sample code:
public class TestSampleEncap
{
public static void main (String[] args)
{
obj.setIdNumber(0419);
obj.setName("Justin");
obj.setAge(34);
System.out.println("Customer ID Number: " + obj.getIdNumber());
System.out.println("Customer Name: " + obj.getName());
System.out.println("Customer Age: " + obj.getAge());
}
}
As you can see, there are two basic components to this code: Inputting the customer information to be checked via the system output upon completing execution. In this case, we should have the following output results:
Customer ID Number: 0419
Customer Name: Justin
Customer Age: 34
3 Common Data Encapsulation Errors
While defining and using getters and setters is relatively straightforward, keep an eye out for these three common errors. Each of them demonstrates how even the smallest coding problem can keep your data from being hidden as intended.
Variable is Less Restricted than in the Getter & Setter
Look closely at what's happening here:
public String idNumber;
public void setIdNumber(String id) {
this.idNumber = id;
}
public String getIdNumber() {
return this.idNumber.
}
While the setter and getter are set up correctly, that's a moot point because the intial idNumber string has been defined as public in the first line. Variable data can now be accessed directly by using the dot (.) operator. To avoid this problem, the first line of code should be rewritten to incorporate a restricted access modifier:
private String idNumber;
Getter Contains Returned Object Reference
Now, let's examine this getter to display a student's grades in a class:
private int[] grades;
public int[] getGrades() {
return this.grades;
}
Then, we use this code to create an array with the grades in it:
int[] myGrades = {80, 50, 70, 90, 85};
setGrades(myGrades);
displayGrades();
int[] copyGrades = getGrades();
copyGrades[1] = 1;
displayGrades();
The issue is the following mismatched results will be generated:
80 50 70 90 85
80 1 70 90 85
The problem is at line 5 of the getter code because this method as defined returns the reference of the internal variable grades directly. The effect is outside code can also access this reference and make changes to the object.
Don't directly return the reference in the getter. Instead, return an object copy. That way, outside code can only ever access a copy, not the actual internal object itself. So, rewrite the getter like this:
public int[] getGrades() {
int[] copy = new int[this.grades.length];
System.arraycopy(this.grades, 0, copy, 0, copy.length);
return copy;
}
Our data is now actually encapsulated and inaccessible to unauthorized code.
Setter Contains Assigned Object Reference
Here's another problem worth discussing. First, look at this setter code for a gradebook:
private int[] grades;
public void setGrades(int[] grd) {
this.grades = grd;
}
So far, so good, right? This code below, however, will demonstrate the issue we ultimately encounter:
int[] myGrades = {80, 50, 70, 90, 85};
setGrades(myGrades);
displayGrades();
myGrades[1] = 1;
displayGrades();
The problem finally shows up with this code to display the grades:
public void displayGrades() {
for (int i = 0; i < this.grades.length; i++) {
System.out.print(this.grades[i] + " ");
}
System.out.println();
}
Right now, the values produced by lines 2 and 3 above will be the same:
80 50 70 90 85
There's a problem, though, with line 4 if we rewrite it like this, which changes the second element in the array:
myGrades[1] = 1;
Now, if we execute the display Grades code again, look at what happens to the second number in the array:
80 1 70 90 85
The grade has changed from a 50 to a 1. Sure, this seems a bit convoluted to be much of an issue, but the problem is data has been manipulated outside of the setter's parameters which we defined earlier. Once again, let's look at the method to set Grades:
public void setGrades(int[] grd) {
this.grades = grd;
}
Here's the problem: The grades variable is directly assigned to the method’s parameter variable grid. The result is both variables refer to the same object: the myGrades array. Any changes made to these grades variables or the myGrades variable will affect the same object.
The solution is to copy elements one by one from the grd array to the grades array. Your updated setter code should look like this:
public void setGrades(int[] grd) {
this.grades = new int[grd.length];
System.arraycopy(grd, 0, this.grades, 0, grd.length);
}
The resulting output from lines 2 and 3 of the display code will now be consistent as myGrades[1] = 1; no longer affects the array grades:
80 50 70 90 85
80 50 70 90 85
Remember: When passing an object reference into a setter, don’t subsequently copy the reference into the internal variable. Instead, copy elements from one array to another by utilizing the method System.arraycopy().
Data Encapsulation Resources
The first place to learn more about data encapsulation in Java is at Oracle's Java Development Kit (JDK) knowledge base. You can access a variety of different resources – API documentation, videos, and downloadable books – for each JDK release version.
In addition, you should check out Encapsulation in Java OOPs. This extensive tutorial uses video and screenshots to discuss how encapsulation and data hiding work in Java. Plus, there's an interesting section on how data hiding can, for example, protect bank accounts from hackers.
While the ins and outs of data encapsulation and its getters and setters can be a bit overwhelming at first, it's critical you effectively incorporate these methods into your Java programming. After all, it's not just that you need to protect data from being accessed or manipulated by outside hackers. You must also restrict access to only those people who need to work with it.
Leave a Reply