Access Modifiers
Access modifiers in Java control the visibility and accessibility of classes, variables, methods, and constructors. They are a core mechanism for encapsulation, security, and clean API design. This is a must-know interview topic and heavily used in real-world Java projects.
What Are Access Modifiers?
- Keywords that define where a member can be accessed from
- Enforce data hiding and controlled exposure
- Applied to classes, methods, variables, and constructors
Types of Access Modifiers in Java
Java provides four access levels:
- private
- default (no keyword)
- protected
- public
Access Level Hierarchy (Least → Most Accessible)
private < default < protected < public
1. private
- Accessible only within the same class
- Most restrictive
- Commonly used for instance variables
class Student {
private int age;
private void calculate() { }
}
- ✔ Supports strong encapsulation
- ❌ Not accessible outside the class
2. default (Package-Private)
- No keyword used
- Accessible within the same package only
- Not accessible from outside the package
class Student {
int marks; // default access
}
- ✔ Useful for package-level collaboration
- ❌ No access across packages
3. protected
- Accessible within the same package
- Accessible in subclasses, even in different packages
class Parent {
protected int value;
}
- ✔ Useful in inheritance
- ✔ Common in framework design
4. public
- Accessible from anywhere
- Least restrictive
- Used for APIs, entry points, and services
public class Student {
public void display() { }
}
- ✔ Required for main() method
- ✔ Used for externally exposed functionality
Access Modifiers Visibility Table (Interview Favorite)
| Access Modifier | Same Class | Same Package | Subclass (diff pkg) | Everywhere |
|---|---|---|---|---|
| private | ✔ | ❌ | ❌ | ❌ |
| default | ✔ | ✔ | ❌ | ❌ |
| protected | ✔ | ✔ | ✔ | ❌ |
| public | ✔ | ✔ | ✔ | ✔ |
Access Modifiers with Class Declaration
Top-Level Classes
- Only public and default are allowed
public class Test { }
class Helper { } // default
❌ private and protected are not allowed for top-level classes.
Access Modifiers with Constructors
class Example {
private Example() { } // restrict object creation
public Example(int x) { }
}
- ✔ Used in Singleton pattern
- ✔ Controls object creation
Access Modifiers and Encapsulation (Best Practice)
class Account {
private double balance;
public double getBalance() {
return balance;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
}
- Data hidden
- Controlled access
- Business rules enforced
Common Beginner Mistakes
- Making variables public
- Confusing protected with default
- Assuming protected means package-only
- Overexposing internal methods
- Not understanding package boundaries
Interview-Ready Answers
Short Answer
Access modifiers control the visibility of classes, variables, and methods in Java.
Detailed Answer
Java provides four access modifiers: private, default, protected, and public. They define where a class member can be accessed from and are essential for encapsulation, security, and maintainable object-oriented design.
Key Takeaway
Use the most restrictive access level possible. Good access control leads to secure, maintainable, and flexible Java applications.
Access Modifiers Examples (Interview Friendly)
1. private – Accessible Only Within Same Class
class Demo {
private int x = 10;
private void show() {
System.out.println(x);
}
public static void main(String[] args) {
Demo d = new Demo();
d.show();
}
}
Explanation
private members accessible only inside the same class
Output: 10
2. private Not Accessible Outside Class
class A {
private int x = 10;
}
class B {
public static void main(String[] args) {
A a = new A();
// System.out.println(a.x); // Compile-time error
}
}
Explanation
Even same package cannot access private
3. Default (No Modifier) – Package-Private Access
class A {
int x = 10; // default access
}
class B {
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
}
}
Explanation
Accessible within same package
Output: 10
4. Default Access – Not Visible Outside Package
// package p1;
class A {
int x = 10;
}
// package p2;
class B {
public static void main(String[] args) {
// new A().x; // Compile-time error
}
}
Explanation
Default access is package-level only
5. public – Accessible Everywhere
public class A {
public int x = 10;
}
class B {
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
}
}
Explanation
public has no access restriction
Output: 10
6. protected – Same Package Access
class A {
protected int x = 10;
}
class B {
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
}
}
Explanation
protected works like default inside same package
Output: 10
7. protected – Access via Inheritance (Different Package)
// package p1;
class A {
protected int x = 10;
}
// package p2;
class B extends A {
public static void main(String[] args) {
B b = new B();
System.out.println(b.x);
}
}
Explanation
protected accessible through inheritance
Output: 10
8. protected Not Accessible via Object (Different Package)
// package p1;
class A {
protected int x = 10;
}
// package p2;
class B {
public static void main(String[] args) {
A a = new A();
// System.out.println(a.x); // Compile-time error
}
}
Explanation
Must use subclass reference, not parent object
9. Access Modifiers on Methods
class A {
protected void show() {
System.out.println("Protected Method");
}
}
class B extends A {
public static void main(String[] args) {
new B().show();
}
}
Explanation
Same rules apply to methods
Output: Protected Method
10. Overriding Method – Cannot Reduce Visibility
class A {
protected void show() {}
}
class B extends A {
// void show() {} // Compile-time error (cannot reduce visibility)
}
Explanation
Overridden method must be same or more accessible
11. Increasing Visibility While Overriding
class A {
protected void show() {
System.out.println("A");
}
}
class B extends A {
public void show() {
System.out.println("B");
}
public static void main(String[] args) {
new B().show();
}
}
Explanation
Visibility increased (protected → public)
Output: B
12. Access Modifiers with Constructors
class A {
private A() {
System.out.println("Private Constructor");
}
public static void main(String[] args) {
new A();
}
}
Explanation
Constructor can be private
Used in Singleton pattern
13. private Constructor Prevents Object Creation
class A {
private A() {}
}
class B {
public static void main(String[] args) {
// new A(); // Compile-time error
}
}
Explanation
Object creation blocked outside class
14. Access Modifiers with Variables (Encapsulation)
class User {
private int age;
public int getAge() {
return age;
}
}
Explanation
Encapsulation uses private + public methods
15. Class-Level Access Modifiers
public class A {}
// protected class B {} // ❌ not allowed
// private class C {} // ❌ not allowed
Explanation
Top-level classes can be only public or default
16. Nested Class Access Modifiers
class Outer {
private class Inner {
void show() {
System.out.println("Inner");
}
}
void call() {
new Inner().show();
}
public static void main(String[] args) {
new Outer().call();
}
}
Explanation
Inner classes can be private
Output: Inner
17. Access Modifier Matrix (Conceptual)
/*
Modifier Same Class Same Package Subclass Other Package
private ✔ ✘ ✘ ✘
default ✔ ✔ ✘ ✘
protected ✔ ✔ ✔ ✘*
public ✔ ✔ ✔ ✔
*/
Explanation
protected across packages only via inheritance
18. Access Modifiers and Static Members
class A {
protected static int x = 10;
}
class B extends A {
public static void main(String[] args) {
System.out.println(x);
}
}
Explanation
Same access rules apply to static members
Output: 10
19. Common Interview Trap
class A {
protected int x = 10;
}
class B {
void test() {
A a = new A();
// System.out.println(a.x); // error if different package
}
}
Explanation
protected ≠ public across packages
20. Interview Summary – Access Modifiers
class Demo {
private int a = 10;
int b = 20;
protected int c = 30;
public int d = 40;
}
Explanation
private → class only
default → package
protected → package + subclass
public → everywhere