An access modifier, sometimes also termed as access specifier, provides the privilege to put restrictions on accessing a class, its attributes ( variable ) and its behavior (method). Java supports four access controls and applies on every class and their variables and methods by default, whether you have explicitly provided it or not.
In other words, an access modifier is an access control mechanism used by Java to manage the visibility or scope of a class and its members. There are two access levels :
1) At the top level : By default, Java marks a class as package private if no modifier is provided explicitly. Otherwise, a programmer is only allowed for declaring it as public.
2) At the member level : In this case, a data member and member function of a class have the privilege to be declared as public, private, protected and default.
Always remember, a class can be declared with the public or default access modifier only, the other two are not legal in Java for a class.
Access control level for Class
- Default: When you declare a class without providing any access modifier, it gets default modifier. For example, if class A and B are in the same package then class A can be accessible to B, however, both are in different packages, then class A would not be accessible to class B.
- Public: Class with public keyword would be considered universally accessible from everywhere, despite that if that class is in a different package then that public class needs to be imported. For example, if class A and B are in the same package then class A can be accessible to B. If both are in a different package, then class A would be accessible to class B when you import class A for B.
Access control level for Class members
Java provides 4 access modifier – Default, public, private and protected. All these modifiers are applicable to the class members.
1. Public: When a class member is preceded with a public keyword then that member can be accessed by other code either from the same package or from other packages.
- Can be accessed to the code from anywhere either from the same package or outside the package.
2. Private: When a class member preceded with a private keyword then only the members of the same class can access it. A method with this modifier can never be overridden.
- Accessible to the class only.
3. Default: When no keyword is explicitly provided to the class members, then by default it acts like public except it can’t accessible to the code outside the package.
- No modifier needed. Accessible to the package only, not outside the packages.
4. Protected: The role of protected keyword comes in play when the inheritance concept is used. In this, When a class member preceded with a protected keyword then the member can be accessible to the code belong to its own class or child class.
- Accessible to the code resides in the same package and to all the subclasses.
[Also Read: Difference between public, private, protected and default in Java]
Let’s discuss these 4 types in brief :
Java Public Access Modifier
- The “public” keyword is used to declare a class or its member as public
- It is a top-level and member-level access modifier
- It applies on both a class and its members
- It makes a class accessible from anywhere in the program, either inside a package or outside a package.
- It is most accessible as compared to all modifiers
Java Default Access Modifier
- When no modifier is provided explicit, Java treats that particular class or members as package-private or default
- It is a top-level and member-level access modifier
- It applies on both a class and its members
- It makes a class accessible within the same package only, not outside the package.
- It provides greater accessibility or scope as compared to private access modifier
Java Protected Access Modifier
- The “protected” keyword is used to declare a member of a class as protected
- It is a member-level access modifier
- It applies only on members of a class
- It makes a method or field accessible within same package and from subclass in different packages
- It provides greater accessibility scope than default access modifier
Java Private Access Modifier
- The “private” keyword is used to declare a member of a class as private
- It is a member-level access modifier
- It applies only on members of a class
- It make a method or field accessible within a class in which it is declared
- It is most restricted access modifier among all
Class visibility control and access modifiers with program Example
A package is a container that consists of related classes and interfaces. In other words, It is a namespace ( that provides a private region or container for grouping ).
Case 1. If a class and its methods are public then it would accessible to other classes within the same package and can also be accessed by the class from a different package.
Case 2. If a class’s methods are protected then it would still be accessible to other classes within the same package. Additionally, it can’t be accessed by non-subclasses but is accessible to subclasses that are from a different package.
Case 3. With a private modifier, a class’s method can neither be accessed by class in the same package nor classes from a different package.
Case 4. If no modifier is specified, then the classes within the same package can only communicate but not with classes from a different package.
Java Programs and Code Examples on Access Modifiers
- Different classes within different Package:
Suppose, we are having two packages “house1“ and “house2“ which consists one class each named “Person1” and “Person2”. “Person2” has 4 methods with different access modifiers i.e private, public, protected, and no-modifier. Below is an example to validate the behavior of accessing methods of a class by another class from a different package.
Class Person1 within House1 Package
package house1; import house2.Person2; package house1; import house2.Person2; public class Person1 { public String name; public String message; public Person1() { this.name = "Kui"; this.message = "Hi"; } public void communicateMethod(Person2 person2) { person2.publicCommunication(); } public String getMessage() { return message; } public String getName() { return name; } public static void main(String[] args) { Person1 person1 = new Person1(); Person2 person2 = new Person2(); System.out.println("Communicating ............... "+person2.getName()); person1.communicateMethod(person2); }
Class Person2 within House2 Package
package house2; public class Person2 { public String name; public Person2() { this.name = "Azen"; } public void publicCommunication(){ System.out.println(this.name+ " Person2 : You have public method access "); } void defaultCommunication(){ System.out.println(this.name+ " Person2 : You have default method access "); } private void privateCommunication(){ System.out.println(this.name+ " Person2 : You have private method access "); } protected void protectedCommunication(){ System.out.println(this.name+ " Person2 : You have protected method access "); } public String getName() { return name; } }
Output:
Azen Person2 : You have public method access
Outcome:
1) A class can access only a public method of other class.
2) A class cannot access any private, protected and no modifier( default) method of other class.
- A class and its subclass in different Packages:
In this, we have used same classes and packages, except now Person1 class is inheriting Person2 class. Inheritance allows a class to have properties of other class. Below is the example to validate the behaviour of a subclass’s accessibility of a super class in different package.
Class Person1 within House1 Package:
package house1; import house2.Person2; public class Person1 extends Person2 { public String name; public String message; public Person1() { this.name = "Kui"; this.message = "Hi"; } public void communicate() { this.publicCommunication(); this.protectedCommunication(); } public String getMessage() { return message; } public String getName() { return name; } public static void main(String[] args) { Person1 person1 = new Person1(); Person2 person2 = new Person2(); System.out.println("Communicating ............... "+person2.getName()); person1.communicate(); } }
Class Person2 within House2 Package
package house2; public class Person2 { public String name; public Person2() { this.name = "Azen"; } public void publicCommunication(){ System.out.println(this.name+ " Person2 : You have public method access "); } void defaultCommunication(){ System.out.println(this.name+ " Person2 : You have default method access "); } private void privateCommunication(){ System.out.println(this.name+ " Person2 : You have private method access "); } protected void protectedCommunication(){ System.out.println(this.name+ " Person2 : You have protected method access "); } public String getName() { return name; } }
Output:
Azen Person2 : You have public method access
Azen Person2 : You have protected method access
Outcome :
1) A subclass in a different package has the accessibility of public and protected members of the other class.
2) A subclass still doesn’t have access to private and non-modifier (default) members.
- Different classes within the same package:
In this scenerio, Person1 and Person2 are in the same package named house1 . Below is an example to validate the accessibility of two classes within the same package.
Class Person1 within House1 Package
package house1; public class Person1 { public String name; public String message; public Person1() { this.name = "Kui"; this.message = "Hi"; } public void communicate(){ } public void communicateMethod(Person2 person2) { person2.publicCommunication(); person2.defaultCommunication(); person2.protectedCommunication(); } public String getMessage() { return message; } public String getName() { return name; } public static void main(String[] args) { Person1 person1 = new Person1(); Person2 person2 = new Person2(); System.out.println("Communicating ............... "+person2.getName()); person1.communicateMethod(person2); } }
Class Person2 within House1 Package
package house1; public class Person2 { public String name; public Person2() { this.name = "Azen"; } public void publicCommunication(){ System.out.println(this.name+ " Person2 : You have public method access "); } void defaultCommunication(){ System.out.println(this.name+ " Person2 : You have default method access "); } private void privateCommunication(){ System.out.println(this.name+ " Person2 : You have private method access "); } protected void protectedCommunication(){ System.out.println(this.name+ " Person2 : You have protected method access "); } public String getName() { return name; } }
Output:
Azen Person2 : You have public method access
Azen Person2 : You have default method access Azen Person2 : You have protected method access
Outcome :
1) A class can access default, public and protected members of another class
2) A class cannot access to private members even if both are in the same package.
- A class and its subclass within same package:
In this scenario, both classes are in the same package and one class is inheriting another class. Below is the program to explain the accessibility of subclass when both belong to the same package.
Class Person1 within House1 Package:
package house1; public class Person1 extends Person2 { public String name; public String message; public Person1() { this.name = "Kui"; this.message = "Hi"; } public void communicate(){ this.protectedCommunication(); this.publicCommunication(); this.defaultCommunication(); } public void communicateMethod(Person2 person2) { } public String getMessage() { return message; } public String getName() { return name; } public static void main(String[] args) { Person1 person1 = new Person1(); Person2 person2 = new Person2(); System.out.println("Communicating ............... "+person2.getName()); person1.communicate(); } }
Class Person2 within House1 Package
package house1; public class Person2 { public String name; public Person2() { this.name = "Azen"; } public void publicCommunication(){ System.out.println(this.name+ " Person2 : You have public method access "); } void defaultCommunication(){ System.out.println(this.name+ " Person2 : You have default method access "); } private void privateCommunication(){ System.out.println(this.name+ " Person2 : You have private method access "); } protected void protectedCommunication(){ System.out.println(this.name+ " Person2 : You have protected method access "); } public String getName() { return name; } }
Output:
Azen Person2 : You have protected method access Azen Person2 : You have public method access Azen Person2 : You have protected method access
Outcome:
1) A subclass has access to protected, default, and public members of the super class
2) The subclass still doesn’t have access to private members.