Java FAQ: Top Questions
6. What are Java access modifiers?
Java access modifiers are keywords that set the accessibility (or visibility) level of classes, fields (variables), methods, and constructors. They are a fundamental part of Java's encapsulation mechanism, allowing developers to control which parts of their code can be accessed from other parts of the program. This helps in achieving data hiding and modularity.
There are four main access modifiers in Java:
-
public
:-
Accessible everywhere. Members (classes, methods, fields, constructors) declared
public
can be accessed from any other class, regardless of the package they are in. -
Detailed Explanation: This is the least restrictive access level. When a member is declared
public
, it means it is fully exposed and intended for use by any other part of the application or even by external libraries. Public members form the public API of a class or package. -
Example:
// In Package A: com.example.packageA package com.example.packageA; public class PublicExample { public int publicVariable = 10; public void publicMethod() { System.out.println("This is a public method."); } } // In another class in Package A: class AnotherClassInA { public void testAccess() { PublicExample obj = new PublicExample(); System.out.println("Accessing publicVariable: " + obj.publicVariable); // Accessible obj.publicMethod(); // Accessible } } // In Package B: com.example.packageB // (Requires importing com.example.packageA.PublicExample) package com.example.packageB; import com.example.packageA.PublicExample; public class TestPublicAccess { public static void main(String[] args) { PublicExample obj = new PublicExample(); System.out.println("Accessing publicVariable from another package: " + obj.publicVariable); // Accessible obj.publicMethod(); // Accessible } }
As seen,
publicVariable
andpublicMethod()
are accessible from both classes within the same package and classes in different packages after import.
-
Accessible everywhere. Members (classes, methods, fields, constructors) declared
-
protected
:- Accessible within the same package and by subclasses (even if the subclass is in a different package).
-
Detailed Explanation: This access level is primarily used for inheritance. A
protected
member is visible to all classes within its own package. Additionally, any class that inherits from the class containing theprotected
member (regardless of its package) can access that member. It promotes controlled inheritance where subclasses can extend and customize behavior while restricting direct access from unrelated classes outside the package. -
Example:
// In Package A: com.example.packageA package com.example.packageA; public class ProtectedExample { protected int protectedVariable = 20; protected void protectedMethod() { System.out.println("This is a protected method."); } } class AnotherClassInA_Protected { public void testAccess() { ProtectedExample obj = new ProtectedExample(); System.out.println("Accessing protectedVariable (same package): " + obj.protectedVariable); // Accessible obj.protectedMethod(); // Accessible } } // In Package B: com.example.packageB // (Requires importing com.example.packageA.ProtectedExample) package com.example.packageB; import com.example.packageA.ProtectedExample; class SubclassInB extends ProtectedExample { // Subclass in a different package public void testAccess() { // Accessing protected members via inheritance System.out.println("Accessing protectedVariable (subclass): " + protectedVariable); // Accessible protectedMethod(); // Accessible // Note: You cannot directly access protected members of a ProtectedExample // object from *outside* the subclass in a different package. // ProtectedExample obj = new ProtectedExample(); // obj.protectedVariable; // NOT accessible here directly (only through inheritance or in same package) } } public class TestProtectedAccess { public static void main(String[] args) { // Access from unrelated class in different package: NOT ACCESSIBLE // ProtectedExample obj = new ProtectedExample(); // System.out.println(obj.protectedVariable); // Compile-time error // obj.protectedMethod(); // Compile-time error SubclassInB subObj = new SubclassInB(); subObj.testAccess(); // Calls the method within the subclass, which has access } }
The
protectedVariable
andprotectedMethod()
are accessible withincom.example.packageA
and bySubclassInB
(which extendsProtectedExample
) even though it's in a different package. An unrelated class inpackageB
cannot directly access them.
-
default
(Package-Private):- If no access modifier is specified, it's considered default (also known as package-private). Accessible only within the same package.
-
Detailed Explanation: This is the default access level if you don't explicitly use
public
,protected
, orprivate
. Members with default access are only visible to classes within the same Java package. They are not accessible from classes in other packages, even if those classes are subclasses. This is useful for grouping related classes that need to collaborate closely without exposing their internal details to the rest of the application. -
Example:
// In Package A: com.example.packageA package com.example.packageA; class DefaultExample { // Class itself has default access int defaultVariable = 30; // Field has default access void defaultMethod() { // Method has default access System.out.println("This is a default (package-private) method."); } } class AnotherClassInA_Default { public void testAccess() { DefaultExample obj = new DefaultExample(); System.out.println("Accessing defaultVariable (same package): " + obj.defaultVariable); // Accessible obj.defaultMethod(); // Accessible } } // In Package B: com.example.packageB package com.example.packageB; // import com.example.packageA.DefaultExample; // This import would fail if DefaultExample class is not public public class TestDefaultAccess { public static void main(String[] args) { // DefaultExample obj = new DefaultExample(); // Compile-time error: DefaultExample is not public // System.out.println(obj.defaultVariable); // Compile-time error // obj.defaultMethod(); // Compile-time error System.out.println("Cannot access default members from another package."); } }
defaultVariable
anddefaultMethod()
(and even theDefaultExample
class itself) are only accessible from withincom.example.packageA
. Any class incom.example.packageB
will not be able to access them.
-
private
:- Accessible only within the class where they are declared.
-
Detailed Explanation: This is the most restrictive access level.
private
members are only visible and accessible from within the class itself. They cannot be accessed from outside the class, not even by subclasses or classes in the same package. This is the cornerstone of encapsulation, allowing a class to hide its internal implementation details and expose only what is necessary through public methods (getters/setters). -
Example:
// In Package A: com.example.packageA package com.example.packageA; public class PrivateExample { private int privateVariable = 40; // Private field private void privateMethod() { // Private method System.out.println("This is a private method."); } public void accessPrivateMembers() { // Accessible within the same class System.out.println("Accessing privateVariable from inside the class: " + privateVariable); privateMethod(); } } class AnotherClassInA_Private { public void testAccess() { PrivateExample obj = new PrivateExample(); // System.out.println(obj.privateVariable); // Compile-time error // obj.privateMethod(); // Compile-time error System.out.println("Cannot directly access private members from outside the class."); obj.accessPrivateMembers(); // Accessible via a public method } } // In Package B: com.example.packageB package com.example.packageB; import com.example.packageA.PrivateExample; public class TestPrivateAccess { public static void main(String[] args) { PrivateExample obj = new PrivateExample(); // System.out.println(obj.privateVariable); // Compile-time error // obj.privateMethod(); // Compile-time error System.out.println("Cannot directly access private members from another package."); obj.accessPrivateMembers(); // Accessible via a public method } }
privateVariable
andprivateMethod()
can only be directly accessed by other methods within thePrivateExample
class itself. Any attempt to access them from outside (even from a subclass or a class in the same package) will result in a compile-time error. You need a public method (likeaccessPrivateMembers()
) to expose or modify private data in a controlled manner.
Summary of Access Levels (from most to least restrictive):
Modifier | Same Class | Same Package (Subclass) | Same Package (Non-subclass) | Different Package (Subclass) | Different Package (Non-subclass) |
---|---|---|---|---|---|
private |
✔ | ✘ | ✘ | ✘ | ✘ |
default |
✔ | ✔ | ✔ | ✘ | ✘ |
protected |
✔ | ✔ | ✔ | ✔ | ✘ |
public |
✔ | ✔ | ✔ | ✔ | ✔ |
Choosing the right access modifier is critical for designing robust and maintainable Java applications, as it directly impacts encapsulation and the overall structure of your code.