Access Specifiers Concept Simplified in Java

 

Access Specifiers in Java
Access Specifiers in Java

Access Specifiers in Java:

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

Ads code goes here
  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 ) is present in the entities 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 it’s 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.Mostly 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 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 it’s subclass.Also a subclass can not override a non private 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 other package.We need to provide public accessor or public mutator method(setter and getter) in order to access private variables from other class in different package.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 same as 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 which 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.

READ  Class RuleBasedCollator 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 the subclasses in other package.It deals with mainly 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 existing class. To inherit from an existing class we need to extend that class.protected elements can be used only inside the class or it’s 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 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 as 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 does 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 visibility level in between protected and private access. The specifier makes the field visible in all sub classes 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 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 mark 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 classes outside of the package , these elements becomes private.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.

READ  Old Fashioned Coding Style May Help Garbage Collector to Reclaim Memory Quickly

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 :

NoSpecifierVisibilityComment
1fiendly/defaultclasses of the same package and that class
2publicAll
3privateonly that class
4protectedthat class, other class of the same package,child class
5finalthat class and subclassall final elements are constants so can not overridden.
6abstractthat class and child classabstract methods needs to be defined in childclass

Interface:

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 :

Access Modifier—>
Access Location
|
|
/
publicprotectedfriendlyprivate protectedprivate
same classyesyesyesyesyes
sub class in
same package
yesyesyesyesNo
Other classes in
same package
yesyesyesNoNo
sub classes in
other package
yesyesNoyesNo
Non Subclass in
other package
yesNoNoNoNo

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.
READ  How to Create A Basic Calculator In Java Applet

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.

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. 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 Comment

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