Private constructor makes the class not instantiable-Chapter 2 Create and destroy objects-Effective Java study notes 03

The content of the article comes from the book Joshua Bloch-Effective Java (3rd)-2018.chm

Chapter two

Create and unregister objects

Item 4 that cannot be instantiated must have a Private constructor

Enforce noninstantiability with a private constructor

Sometimes you want to write a class that contains only a set of static methods and static fields

Such kind of criticism in the industry, as far as the object is concerned, because some people use it without a brain, but they do have effective uses

  • They can group related methods using primitive values ​​or arrays, using java.lang.Math or java.util.Arrays
  • They can also be used to group static methods of objects that implement certain interfaces, using the java.util.Collections file
  • Or, these classes can be used to group methods into final classes because you cannot put them in subclasses
  • (Java8 and later, you can also put these methods in the interface, if you modify these methods)

Such utility classes are not designed to be instantiated: an example of this kind is meaningless

However, in the absence of an explicit constructor, the compiler provides a public, parameterless default constructor

For users, this constructor is no different from any other constructor

It is not uncommon to accidentally see instantiable classes in published APIs

Trying to enforce non-instantiable by making the class abstract will not work

The class can be a subclass, and the subclass can be instantiated

In addition, it misleads users into thinking that the class is designed for inheritance

However, there is a simple usage to ensure non-instance

The default constructor will only be generated when the class does not have an explicit constructor, so

You can make the class non-instantiable 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 not accessible outside the class

The error AssertionError is not strictly required, but it provides an insurance method to prevent accidental transfer of the constructor from the class

It guarantees that the class will not be instantiated under any circumstances

This idiom is a bit counterintuitive, because the constructor is explicitly provided and cannot be called yet

So like the above example, it is wise to add comments

As a side effect, this idiom also prevents classes from being subclassed

(Under normal circumstances) all constructors must call the parent class constructor, explicit or implicit, (but in this case) the child class will have no accessible parent class constructor to call

Guess you like

Origin blog.csdn.net/weixin_43596589/article/details/112555408