Saturday 21 September 2019

Enforce noninstantiability with a private constructor in Utility classes

Sometimes, we want to write a class that is just a grouping of static methods and static fields. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. These classes are known as Utility classes.

Utility classes can also be used to group static methods, including factories, for objects that implement some interface, in the manner of java.util.Collections.

Such utility classes were not designed to be instantiated: an instance would be nonsensical. In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. It is not uncommon to see unintentionally instantiable classes in published APIs.

Attempting to enforce noninstantiability by making a class abstract does not work. The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance.

There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

// Noninstantiable utility class
public class UtilityClass {
     // Suppress default constructor for noninstantiability
     private UtilityClass() {
          throw new AssertionError();
     }
     // Remainder omitted
}

Because the explicit constructor is private, it is inaccessible outside the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive because the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown earlier.

As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

Java Tutorials | Access Modifiers in Java

The access modifiers in Java specifies the accessibility or scope of a field, method, constructor, or class. We can change the access level of fields, constructors, methods, and class by applying the access modifier on it.

There are four types of Java access modifiers:
1.    Private Access modifier
2.   Default Access modifier
3.    Protected Access modifier
4.   Public Access modifier

To understand Java Access Modifiers, see below given table:

1. Private Access modifier
It is specified using the keyword private. The methods or data members declared as private are accessible only within the class in which they are declared.

Any other class of the same package will not be able to access these members. Top level classes or interface cannot be declared private as “only visible within the enclosing class”.

Protected means “only visible within the enclosing class and any subclasses”
Hence these modifiers in terms of application to classes, they apply only to nested classes and not on top level classes

// Error while calling a private method from different class
public class ClassA {
     private void display() {
          System.out.println("GeeksforGeeks");
     }
}

class ClassB {
     public static void main(String args[]) {
          ClassA obj = new ClassA();
          // trying to access private method of another class
          obj.display();
     }
} 
Output:
error: display() has private access in ClassA obj.display();               

2. Default Access modifier
When no access modifier is specified for a class, method or data member – It is said to be having the default access modifier by default. Default modifiers are accessible only within the same package.

Example, we will create two packages and the classes in the packages will be having the default access modifiers and we will try to access a class from one package from a class of second package.

// ClassB is having Default access modifier
package com.b;
class ClassB {
     void display() {
          System.out.println("Hello World!");
     }
}

package com.a;
import com.b.ClassB;
public class ClassA {
     public static void main(String args[]) {
          ClassB obj = new ClassB();
          obj.display();
     }
}
Output: The method display() from the type ClassB is not visible

3. Protected Access modifier
The access level of a protected modifier is within the package and outside the package through child class. If you do not make the child class, it cannot be accessed from outside the package.

// ClassB is having protected access modifier
package com.b;
class ClassB {
     protected void display() {
          System.out.println("Hello World!");
     }
}

package com.a;
import com.b.ClassB;
public class ClassA {
     public static void main(String args[]) {
          ClassA obj = new ClassA();
          obj.display();
     }
}
Output: Hello World!

4. Public Access modifier
The access level of a public modifier is everywhere. It can be accessed from within the class, outside the class, within the package and outside the package.
There are many non-access modifiers, such as static, abstract, synchronized, native, volatile, transient, etc. Here, we are going to learn the access modifiers only.
Related Posts Plugin for WordPress, Blogger...