7 Access Specifiers in Java: Simplified Concept

Introduction to Access Specifiers in Java

Access specification is the mechanism by which we can control the use of the objects, their members, and methods.
Below are the access specifier available in Java:

  1. public
  2. private
  3. protected
  4. final
  5. private and protected
  6. abstract
  7. friendly/default

Java access control mechanism (JLS-6.6) determines the accessibility of classes, interfaces, and members.

The accessibility of an entity is determined by the location where it is declared and by which if any access modifiers (private protected and public ) are present in the entity’s declaration.

By proper using of these, we can hide information from users. The rule of thumb is that we should make each class or member as inaccessible as possible.

For top-level (non-nested) classes and interfaces, there are only two possible access levels(Package –Private and public).

If we declare a top-level class or interface with the public Modifier, it will be public. Otherwise, it will be package-private.

If a package-private top-level class or interface is used only within a single class, we need to consider making it a private nested class( or interface) of the class in which it is used.

This further reduces its accessibility, It is however not as important to do this as it is to make an unnecessary public class package private because a package-private class is already part of the package’s implementation rather than APIs.

public Access Specifier:

public classes, methods can be accessed from any other classes, methods. The public access specifier is optional and automatic.

Most customer-facing methods of a class are public in nature so that they can accept calls from other classes. So an element with public access specifier has the widest possible visibility and accessibility.

private Access Specifier: 

Elements with private access specifiers are having the highest degree of protection. private elements, methods can only be accessed from that class where it is defined. A private element or method is not visible to any other class or its subclass.

Also, a subclass can not override a nonprivate method and make a new private method. This is useful when we want to exclude classes that should not have access to the classes being defined in another package.

We need to provide a public accessor or public mutator method(setter and getter) in order to access private variables from other classes in different packages.in a simple word, the private access modifier specifies that no member except that particular class(inside methods of that class).

Other classes in the same package can not access private members. A protected element is the same as the final.
private allows developers to work on some data members without affecting the user’s code. It is also very important in terms of multi-threading coding.

Any method for that class that acts as a ‘helper can be made private to ensure that it is not used in the package or anywhere else thus prohibits us from changing or removing the method.Private methods are the helper function in java.
A class member declared as private will remain private to its class. It is not accessible by any class outside its class including its subclass.

See also  SequentialInputStream in Java

Package private

The member is accessible from any class in the package where it is declared. Technically known as default access. This is the access level we get if no access modifier is specified.

protected Access Specifier:

protected elements are between public and default/friendly or Protected is sort of private. The protected elements are visible not only to all classes and subclasses in the same package but also to the subclasses in another package.

It deals with the main inheritance which takes an existing class and adds new members to another class without touching the existing class(base class).

We can change the methods of an existing class. To inherit from an existing class we need to extend that class.

protected elements can be used only inside the class or the subclass. An inherited class can access a protected members as well as public members.

A subclass can override a protected method and variable. Non-subclasses in the other packages can not access the protected elements.
class ClassA extends ClassB{

That is if a class inherits another class of another package, the only members we have access are public members of the base class(if we are inheriting a class of the same package-we will have access to friendly/default members) and all the protected members of the class.

If the creator of the base class wants to give access to some of its members to the derived classes but not to the whole world.

then protected modifier is the best suitable. A protected method has friendly access within the same package.

public and protected can not be applied to a class. As they do not make any sense. A class can not be private as it would make it accessible to no one but the class itself.
If we want not to have anyone access to the class,we can make all the constructor private, that prevents anyone but us,inside a static member of the class from creating an object of that class.

class ClassA{
private ClassA()
static ClassA makeObjectA()
return new ClassA();
public class MyClass{
public static void main(String args[])
ClassA ca=new ClassA();
//not possible to call the constructor as it is private
ClassA ca=ClassA.makeObjectA();
//returns the object of the class ClassA.This is how we create an object,preventing anyone from directly accessing a particular constructor or constructors.

final Access Specifier:

All final elements of a class can not be overridden by subclasses of that class. classes can also be declared as final which denotes that the same class can not be subclassed. Please refer final keyword here.

private protected Access Specifier:

A field can be declared with two keywords private and protected together like:

private protected int codeName;

This gives a visibility level in between protected and private access. The specifier makes the field visible in all subclasses regardless of what package they are in. These fields are not accessible by other classes in the same package.

abstract Access Specifier:

if anybody wants to define the method in a subclass, he can choose to use abstract keyword to mark it. In case of method , the method has to be defined in subclass. In the case of class, it signifies that the class is not fully implemented and it should not be instantiated.

friendly/default Access Specifier:

In case no access specifier is specified, java by default marks an element as default/friendly. It is a special version of public specifier. It means all other classes in the same package have access to these friendly members but for classes outside of the package, these elements become private.

See also  Empty Statements in Java

Since a compilation unit(a file) can only belong to a single package, all the classes within a single compilation units are automatically friendly with each other.

It allows us to group related classes together in a package so that they can easily interact with each other. (granting mutual access to all the friendly elements of the package to each other).

An inherited class can access friendly/default members if both the class belong to same package.

So the difference between public and default specifier is that the public makes elements visible in all classes regardless of their package but friendly makes an element visible only in the same package but not in other packages.

public class ClassA{
int x;
private String s;
public void getData()
final void deleteData()
private void printData()
class ClassB extends ClassA{
// ClassB can access public and protected methods or elements of ClassA . However it can not override deleteData().
final class ClassC{
class ClassD extends ClassC{
//compilation error as ClassC is final hence can not be subclasses or extended.
abstract ClassE{
abstract void myMethod();
public class classF{
public static vois main(String args[])
ClassE def=new ClassE();
//compilation error as ClassE is an abstract class hence can not be instanciated

Here is a shortcut table to remember :

1fiendly/default classes of the same package and that class2publicAll3privateonly that class4protectedthat class, other class of the same package,child class5finalthat class and subclassall final elements are constants so can not overridden.6abstractthat class and child classabstract methods needs to be defined in childclass



Access control is often referred to as implementation hiding.Wrapping data and methods within classes(combined with implementation hiding,this is often called encapsulation) produces a data type with characteristics and behaviors ,but access control puts boundaries within that data type for the below reason:

  • This is to establish what client programmer can and can’t use.We can build our internal mechanism into the structure without worrying that the client programmers will think it is part of the interface they should be using.
  • This separates the interface from implementation. If the structure is used in a set of programs ,but the users can’t do anything but send message to the public interface then we can change anything that is not public(example-default/friendly,protected or private) without requiring modification to their code.

Another view to remember :

same classyesyesyesyesyessub class insame packageyesyesyesyesNoOther classes insame packageyesyesyesNoNosub classes inother packageyesyesNoyesNoNon Subclass inother packageyesNoNoNoNo

Access Modifier->
Access Location
publicprotectedfriendlyprivate protectedprivate

General rule of thumb while choosing Specifiers:

  1. use public if the element is to be visible everywhere.
  2. use protected if the element is to be visible everywhere in the current package and also sub classes in other package.
  3. use default or friendly if the element is to be visible everywhere in the current package only
  4. use private protected if the element is to be visible only in subclasses regardless of packages.
  5. use private if the element is not to be visible anywhere except in its own class.

After carefully design our class’s public APIs, our next step should be to make all other members private.If another class in the same package needs to access member, we must put default modifier for the member not private.

It is always better to decouple the modules from one another. If not done, it may lead to ‘leak’ into exported API if the class implements serializable interface.

See also  Abstract Interface FileNameMap in Java

If a method overrides a superclass method, it is not permitted to have a lower access level in the subclass then it does in the superclass.

Know some amazing Features of Java

This is necessary to ensure that an instance of the subclass is usable anywhere that an instance of the superclass is usable. If we violate this rule, the compiler will generate an error message when we try to compile the subclass.

A special case of this rule is that if a class implements an interface, all of the class methods that are also present in the interface must be declared public. This is because all methods in an interface are implicitly public.

Public classes should rarely have public field but surely have public methods. If a field is non final or is a final reference to a mutable object, we loose the ability to limit the values that may be stored in the fields by making it public.

We also loose the ability to take any actions when the field is modified. A simple consequence is that classes with public mutable fields are not thread safe.

Even if the field is final and does not referred to a mutable object by making the field public, we loose the flexibility to switch to a new internal data representation in which the field does not exists.

However there is an exception to the rule that private classes should not have public fields,that is public class can contain a public field when they are constant via public static final fields.

By convention names of these constants capital letters with words separated by underscore.They can contain either a primitive values or references to immutable objects.

A final field containing a reference to mutable object has all the disadvantages of a normal field. While the reference cannot be modified, the referenced object can be modified.

This is one gateway of bug.

Note that a non-zero length array is always mutable,hence it is very wrong design approach to have public static final array field.

//-A potential security issue

public static final type[] my array={….};

If a class have such field, the user may change the contents of the array. This could be a security concern too. The public array should be replaced by a private array and a public immutable list:-

Private static final type []my array={….};
Public static final List myArrayValues= Collections.unmodifiableList (arrays.asList (my array));

Alternatively, if we need compile time type safe and little slow solution, we can replace the public array field with a public method that returns a copy of private array.

private static final Type[] myarray={…..};
public static final Type [] getMyArray(){
return (Type[]) my array.clone();

Points to Remember

  1. We must reduce accessibility as much as possible .
  2. we need to design the public API is such a way that APIs will not be part of any classes(stray) ,interface or members
  3. Public classes should have no public field except public final static fields .(constants)
  4. Object referenced by public static final fields are immutable.

Share and Enjoy !

Leave a Reply

Your email address will not be published. Required fields are marked *