Access modifiers in Java are keywords used to control the accessibility of classes, methods, and variables. They determine which other classes can access a particular class, method, or variable.
- Private: Access limited to the same class.
- Default (Package-Private): Access limited to the same package.
- Protected: Accessible within the same package and by subclasses.
- Public: Unrestricted access, accessible from any other class.
1. Private Access
In Java, the private
access modifier restricts access to members (fields, methods, nested classes) to only the same class where they are declared. Here’s a breakdown:
- Access Restricted to Same Class: Members marked as
private
can only be accessed within the same class. - Not Accessible Outside the Class: Other classes, even those in the same package or subclasses, cannot access
private
members. - Encapsulation: Encourages encapsulation by hiding implementation details and ensuring that access is controlled through well-defined interfaces.
Here’s a simple example to illustrate private
access:
package packageA;
public class MyClass {
private int privateField;
private void myPrivateMethod() {
// Accessing its own private field
privateField = 20;
}
}
The privateField
is a private member of the MyClass
class. It cannot be accessed directly from outside the MyClass
class. However, within the MyClass
class, such as in the myPrivateMethod()
method, the privateField
can be accessed and modified without any restrictions.
This encapsulation ensures that the internal state of the MyClass
class is hidden from external classes, enhancing data integrity and preventing unintended access or modification of sensitive data.
Now, let’s visualize this with a figure:
----------------- -----------------
| Package A | | Package B |
----------------- -----------------
| MyClassA | | MyClassB |
| [private] | | [private] |
| | -----------------
| |
| AnotherClass |
| [private] |
-----------------
In the figure above:
MyClass
is located inPackage A
.- It has a private member (field or method).
- Classes in
Package B
cannot access the private member ofMyClass
. - Other classes in
Package A
cannot access the private member ofMyClass
.
package packageB;
import packageA.MyClass;
public class AnotherClass {
public void doSomethingElse() {
MyClass obj = new MyClass();
obj.myPrivateMethod(); // Compilation error
}
}
package packageA;
public class AnotherClass {
public AnotherClass() {
MyClass myClass = new MyClass();
System.out.println(myClass.privateField); // Compilation Error
myClass.privateMethod(); // Compilation Error
}
}
2. Default (Package-Private) Access
Default access (also known as package-private) allows members (fields, methods, and constructors) to be accessible within the same package but not from outside the package. It’s the access level used when no access modifier is specified.
Let’s have a look at the figure for this section:
----------------------------------------------
| package packageA |
|--------------------------------------------|
| |
| MyClass |
| ------------------------------------ |
| | privateField: int | |
| | defaultField: int (default) | |
| ------------------------------------ |
| | myPublicMethod() | |
| | myPrivateMethod() | |
| ------------------------------------ |
| |
| |
| |
| AnotherClass |
| ------------------------------------ |
| | myMethod() | |
| ------------------------------------ |
| |
----------------------------------------------
----------------------------------------------
| package packageB |
|--------------------------------------------|
| |
| MyClassB |
| ------------------------------------ |
| | myMethodB() | |
| ------------------------------------ |
| |
----------------------------------------------
Here is a code example to illustrate this:
// MyClass.java
package packageA;
public class MyClass {
private int privateField;
int defaultField;
public void myPublicMethod() {
System.out.println("Public Method");
}
private void myPrivateMethod() {
System.out.println("Private Method");
}
}
// AnotherClass.java
package packageA;
public class AnotherClass {
public void myMethod() {
MyClass myClass = new MyClass();
// Compilation error: privateField has private access in MyClass
System.out.println(myClass.privateField);
// Compilation error: myPrivateMethod() has private access in MyClass
myClass.myPrivateMethod();
// Accessing defaultField
System.out.println(myClass.defaultField);
}
}
// MyClassB.java
package packageB;
import packageA.MyClass;
public class MyClassB {
public void myMethodB() {
MyClass myClass = new MyClass();
// Compilation error: privateField has private access in MyClass
System.out.println(myClass.privateField);
// Compilation error: defaultField has default access in MyClass
System.out.println(myClass.defaultField);
}
}
In this setup:
- MyClass has private and default fields (
privateField
anddefaultField
, respectively). - AnotherClass, in the same package as MyClass, tries to access both private and default fields of MyClass. It can access the defaultField but not the privateField.
- MyClassB, in a different package from MyClass, tries to access both private and default fields of MyClass. It cannot access either the privateField or the defaultField.
3. Protected Access
Protected access is more permissive than private and default access, but more restrictive than public access. It allows access within the same package and from subclasses, even if they are located in different packages.
Here is the figure for this section:
----------------------------------------------
| package packageA |
|--------------------------------------------|
| |
| MyClass |
| ------------------------------------ |
| | privateField: int | |
| | defaultField: int (default) | |
| ------------------------------------ |
| | myPublicMethod() | |
| | myPrivateMethod() | |
| ------------------------------------ |
| |
| AnotherClass |
| ------------------------------------ |
| | myMethod() | |
| ------------------------------------ |
| |
| SubclassA extends MyClass |
| ------------------------------------ |
| | myMethod() | |
| ------------------------------------ |
| |
----------------------------------------------
----------------------------------------------
| package packageB |
|--------------------------------------------|
| |
| MyClassB |
| ------------------------------------ |
| | myMethodB() | |
| ------------------------------------ |
| |
| SubclassB extends MyClass |
| ------------------------------------ |
| | myMethodB() | |
| ------------------------------------ |
| |
| OtherClass |
| ------------------------------------ |
| | otherMethod() | |
| ------------------------------------ |
| |
----------------------------------------------
SubclassA
andSubclassB
are subclasses ofMyClass
in their respective packages.SubclassA
andSubclassB
can access the protected and public members ofMyClass
.OtherClass
is a non-subclass class in each package.OtherClass
cannot access the protected members ofMyClass
unless it is in the same package asMyClass
.
here’s an example illustrating the accessibility of protected members:
package packageA;
public class MyClass {
private int privateField;
int defaultField;
protected int protectedField;
public MyClass() {
this.privateField = 10;
this.defaultField = 20;
this.protectedField = 30;
}
public void accessFields() {
// Accessible within MyClass
System.out.println("Private field: " + privateField);
// Accessible within MyClass and packageA
System.out.println("Default field: " + defaultField);
// Accessible within MyClass, packageA, and subclasses
System.out.println("Protected field: " + protectedField);
}
}
package packageA;
public class AnotherClass {
public void accessFields() {
MyClass myClass = new MyClass();
// Accessing protected field from MyClass
System.out.println(myClass.protectedField);
}
}
package packageB;
import packageA.MyClass;
public class OtherClass {
public void accessFields() {
MyClass myClass = new MyClass();
// Accessing fields from MyClass
System.out.println(myClass.privateField); // compilation error
System.out.println(myClass.defaultField); // compilation error
System.out.println(myClass.protectedField); // compilation error
}
}
package packageB;
import packageA.MyClass;
public class SubclassB extends MyClass {
public void accessFields() {
MyClass myClass = new MyClass();
// Accessing fields from MyClass
System.out.println(myClass.privateField); // compilation error
System.out.println(myClass.defaultField); // compilation error
// Accessible from subclasses
System.out.println(myClass.protectedField);
}
}
privateField
is accessible only within theMyClass
itself.defaultField
is accessible withinMyClass
and any other class in the same package (packageA
).protectedField
is accessible withinMyClass
, any other class in the same package (packageA
), and its subclasses (SubclassB
inpackageB
).
The OtherClass
in packageB
cannot access privateField
or defaultField
from MyClass
because it is in a different package. Similarly, the SubclassB
can access protectedField
because it is a subclass, but it cannot access privateField
or defaultField
directly from MyClass
because they are not visible outside of MyClass
or packageA
. AnotherClass
in packageA
can access the protected fields of MyClass
since it’s in the same package.
4. Public Access
Public access modifier allows members to be accessible from anywhere, both within and outside the package. Public members can be accessed by any other class or package.
Here’s a code example to illustrate public access:
package packageA;
public class MyClass {
public int publicField;
public MyClass() {
this.publicField = 100;
}
public void publicMethod() {
System.out.println("This is a public method.");
}
}
package packageB;
import packageA.MyClass;
public class AnotherClass {
public void accessPublicMembers() {
MyClass myClass = new MyClass();
// Accessing public field and method from MyClass
System.out.println("Public field value: " + myClass.publicField);
myClass.publicMethod();
}
}
In this example, AnotherClass
in packageB
can access the public field and method of MyClass
from packageA
. This demonstrates the public access modifier’s ability to allow members to be accessed from outside the package.