Утилитные классы, которые используют только статические методы и поля, не должны создавать экземпляры. Для этого используется приватный конструктор.
Абстрактный класс не может предотвратить создание экземпляров, поэтому конструктор утилитного класса объявляется приватным, чтобы запретить доступ извне.
Для лучшего понимания к приватному конструктору добавляется комментарий. Также запрещается наследование, что делает назначение класса более ясным.
Иногда бывает полезно использовать классы, содержащие только статические методы и статические поля.
В качестве примера можно привести утилитарные классы, такие как java.lang.Math, java.util.Arrays, которые объединяют методы, связанные с математическими операциями или массивами. Или, например, java.util.Collections, который может содержать статические фабричные методы для создания объектов, реализующих определенный интерфейс.
В таких утилитарных классах нет необходимости в переменных или методах экземпляра, поэтому конструктор не нужен. Однако, если конструктор не объявлен явно, компилятор автоматически создает открытый (public) конструктор по умолчанию. В результате пользователь не может различить, был ли конструктор создан автоматически или явно.
Чтобы предотвратить это, иногда классы объявляют абстрактными, но абстрактные классы не препятствуют созданию экземпляров. Достаточно создать дочерний класс и создать его экземпляр.
Поэтому, чтобы запретить создание экземпляров утилитарного класса, необходимо сделать модификатор доступа конструктора private.
Если модификатор доступа конструктора по умолчанию является private, то доступ к нему извне класса невозможен. Кроме того, если конструктор по умолчанию вызывается изнутри, он генерирует исключение.
Такой private-конструктор может быть сложным для понимания при использовании, поэтому рекомендуется добавлять комментарии. Кстати, если конструктор объявлен как private, это также запрещает наследование.