Access Modifiers in Java

Java

Java is a popular object-oriented programming language that values security, scalability, and resilience. One of its most essential features is using access modifiers to regulate the visibility and accessibility of variables, classes, and methods.

Java’s encapsulation principle relies heavily on access modifiers, which allow programmers to establish boundaries and guarantee data integrity.

Consider collaborating on a project as a team without limitations on who can view or edit each other’s code. There would be havoc! As security measures, access modifiers ensure that only the approved code can interact with particular areas of your application.

Also Read: OOP Concepts in Java

What Are Access Modifiers in Java?

Java keywords known as “access modifiers” control the scope and visibility of variables, constructors, classes, and methods. They are essential for specifying how various sections of your code communicate with one another and with outside elements.

Java offers four different kinds of access modifiers:

  • Public: Accessible from anywhere.
  • Private: Only members of the defined class can access it.
  • Protected: Accessible by subclasses in other packages and within the same package.
  • Default (Package-private):  Only accessible within the same package; no specific keyword is needed.

By using access specifiers in Java, sensitive data can be protected by carefully comprehending and using these modifications. You can also avoid unintended modifications and improve the code’s readability and maintainability.

Access Modifier Types

Let’s examine each access modifier in more detail, including its traits and real-world applications.

1. public Access Modifier

The modifier public permits unrestricted access. Regardless of its package, any other class can access any class, method, or variable declared public.

When to use: When you wish to make globally accessible APIs, constants, or utility methods available.

Example:

package com.example;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
package com.main;
import com.example.Calculator;
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
System.out.println("Sum: " + calculator.add(5, 3)); // Output: Sum: 8
}
}

Code Explanation: 

This Java program demonstrates package usage. The Calculator class (in com.example) provides a method to add two numbers. The Main class (in com.main) imports the Calculator, calls its add method, and prints the result (Sum: 8).

2. private Access Modifier

The private modifier restricts access to the declared class. It is frequently used to build encapsulation by concealing sensitive data and is the most restrictive access level.

When to Use: To guarantee data integrity and safeguard internal class details.

Example:

package com.example;
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public double getBalance() {
return balance;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount(1000);
account.deposit(500);
System.out.println("Balance: " + account.getBalance()); // Output: Balance: 1500
}
}

Code Explanation:

This Java program demonstrates object-oriented programming with a BankAccount class. The class has methods to initialize a balance, deposit money, and retrieve the balance. In the Main class, an account is created with an initial balance of 1000, 500 is deposited, and the updated balance (1500) is printed.

3. protected Access Modifier 

The protected modifier permits access to subclasses in other packages and within the same package. The public and private access levels are balanced.

When to Use: In inheritance-related situations where subclasses require access to members of parent classes.

Example:

package com.example;
public class Animal {
protected String name;
protected void setName(String name) {
this.name = name;
}
protected String getName() {
return name;
}
}
package com.zoo;
import com.example.Animal;
public class Dog extends Animal {
public void display() {
setName("Buddy");
System.out.println("Dog’s Name: " + getName());
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.display(); // Output: Dog’s Name: Buddy
}
}

Code Explanation:

This Java program demonstrates inheritance and access modifiers. The Animal class (in com.example) has protected methods to set and get the animal’s name. The Dog class (in com.zoo) extends Animal, sets the name to “Buddy,” and displays it. The output is Dog’s Name: Buddy.

Also Read: Inheritance in Java

4. Package-Private/Default Access Modifier

The member can only be accessed within the same package if no access modifier is supplied. In Java, this is the default access level.

When to Use: Methods and classes meant to be used exclusively inside a particular package.

Example:

package com.example;
class Helper {
void displayMessage() {
System.out.println("This is a package-private method.");
}
}
public class Main {
public static void main(String[] args) {
Helper helper = new Helper();
helper.displayMessage(); // Output: This is a package-private method.
}
}

Code Explanation:

This Java program demonstrates package-private access. The `Helper` class has a method `displayMessage()` with no access modifier, making it accessible only within the same package (`com.example`). The `Main` class calls this method, producing the output: `This is a package-private method.`

For a deeper understanding of how methods are defined and their role in Java, check out our detailed guide on Methods in Java.

Comparison Table

ModifierClassSame PackageSubclass (Different Package)World
publicYesYesYesYes
protectedYesYesYesNo
DefaultYesYesNoNo
privateYesNoNoNo

Best Practices for Using Access Modifiers

  • Follow the Principle of Least Privilege: Use the most restrictive modifier that allows the desired functionality.
  • Prevent Overexposure: Use public only for classes and methods that require worldwide visibility.
  • Encapsulate Data: Employ private for fields and use getter and setter methods to grant controlled access.
  • Leverage Inheritance Wisely: Use protected for methods and variables intended to be overridden by subclasses.
  • Document Access Levels: Clearly explain the rationale behind selecting a specific access level, particularly for public and protected members.

Common Mistakes and How to Avoid Them

  • Overuse of public: Designating all fields and methods as `public` for convenience.
    • Solution: Determine if the member needs to be reachable outside their class or package.
  • Forgetting to Define an Access Modifier: Ignoring the need to define an access modifier results in unwanted default (package-private) access.
    • Solution: For clarity, always provide an access modifier directly.
  • Misuse of protected: Revealing confidential information via `protected` members.
    • Solution: Only use `protected` when creating inheritance-friendly designs.
  • Ignoring Encapsulation: Using `public` fields with getters and setters rather than private fields.
    • Solution: Always encapsulate fields to maintain data integrity and regulate access.

Access Modifiers with Classes and Interfaces

Class Access Modifiers

  • Public Class: Openable from any other class.
  • Package-Private Class: Accessible only within the same package (default).

Example:

// Default (package-private) class
class InternalClass {
void display() {
System.out.println("Accessible only within the package.");
}
}
public class PublicClass {
public static void main(String[] args) {
InternalClass internal = new InternalClass();
internal.display(); // Output: Accessible only within the package.
}
}

Code Explanation:

This Java program demonstrates the default (package-private) access modifier. The InternalClass class and its display() method are accessible only within the same package. The PublicClass calls this method, resulting in the output: Accessible only within the package.

Access Modifiers for Interfaces

All methods in an interface are `public` by default, and variables are `public static final`.

Example:

public interface Vehicle {
int MAX_SPEED = 120; // public static final by default
void start(); // public by default
}
public class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car is starting. Max speed: " + MAX_SPEED);
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start(); // Output: Car is starting. Max speed: 120
}
}

Code Explanation:

This Java program demonstrates the use of interfaces. The Vehicle interface defines a constant MAX_SPEED and an abstract method start(). The Car class implements the Vehicle interface and provides an implementation for start(). The Main class creates a Car object and calls start(), outputting: Car is starting. Max speed: 120.

Also Read: Difference Between Abstract Class and Interface in Java

Real-world applications for Access Modifiers

  • API Development: Private methods manage internal logic, whereas public methods let outside apps communicate with your library.
  • Frameworks and Libraries: Access modifiers aid in establishing distinct lines between internal implementations and public APIs.
  • Business Applications: Use access modifiers to guarantee encapsulation and modularity in large-scale systems.

Conclusion

Writing Java code that is efficient, secure, and maintainable requires the use of access specifiers. Sensitive data can be protected by using best practices and comprehending their subtleties. For better results, you should avoid inadvertent actions and improve teamwork among your members.

If you are interested in learning Java from scratch, we have a Free Java Programming Course for you.

→ Explore this Curated Program for You ←

Avatar photo
Great Learning Editorial Team
The Great Learning Editorial Staff includes a dynamic team of subject matter experts, instructors, and education professionals who combine their deep industry knowledge with innovative teaching methods. Their mission is to provide learners with the skills and insights needed to excel in their careers, whether through upskilling, reskilling, or transitioning into new fields.

Full Stack Software Development Course from UT Austin

Learn full-stack development and build modern web applications through hands-on projects. Earn a certificate from UT Austin to enhance your career in tech.

4.8 ★ Ratings

Course Duration : 28 Weeks

Cloud Computing PG Program by Great Lakes

Enroll in India's top-rated Cloud Program for comprehensive learning. Earn a prestigious certificate and become proficient in 120+ cloud services. Access live mentorship and dedicated career support.

4.62 ★ (2,760 Ratings)

Course Duration : 8 months

Scroll to Top