Subodh Joshi
Subodh Joshi

Reputation: 13512

Is it mandatory utility class should be final and private constructor?

By making private constructor, we can avoid instantiating class from anywhere outside. and by making class final, no other class can extend it. Why is it necessary for Util class to have private constructor and final class ?

Upvotes: 20

Views: 13590

Answers (5)

Guillaume F.
Guillaume F.

Reputation: 1130

Whether a class should be final has more to do about social norms and conventions, and less about best practices.

In Java, the norm is to treat the clients of a class like children; outside developers are not to be trusted, and should be blocked from doing anything not intended. The philosophy here is that it’s better to disallow something dangerous altogether than to risk someone else getting it wrong.

This reasoning leads to the idea that all classes should be final unless specifically designed to allow inheritance, as inheritance can be very dangerous. In general, utility classes should almost always be final, as they typically are not designed for inheritance.

There are of course other points of view. For example, in Python, the philosophy is that "we're all consenting adults here" - that is, the developer should be warned that something is dangerous but still allowed to do it if they really want to. This leads to "final" and "private" modifiers being suggestions, and not actually enforced by the language itself. Or, in other words, "it is preferable that you stayed out of its living room because you weren't invited, not because it has a shotgun".

The main disadvantage of setting a utility class final is that it makes it quite complicated for other users to add new methods that they need to your class. They will need to write a wrapper class that delegate almost everything to the utility class, instead of just inheriting the class and adding the needed methods directly.

Upvotes: 0

Panther
Panther

Reputation: 3339

This is not a mandate from a functional point of view or java complication or runtime. However, it's a coding standard accepted by the wider community. Even most static code review tools, like checkstyle, check that such classes have this convention followed.

Why this convention is followed is already explained in other answers and even OP covered that, but I'd like to explain it a little further.

Mostly utility classes are a collection of methods/functions which are independent of an object instance. Those are kind of like aggregate functions as they depend only on parameters for return values and are not associated with class variables of the utility class. So, these functions/methods are mostly kept static. As a result, utility classes are, ideally, classes with only static methods. Therefore, any programmer calling these methods doesn't need to instantiate the class. However, some robo-coders (maybe with less experience or interest) will tend to create the object as they believe they need to before calling its method. To avoid that, we have 3 options:

  1. Keep educating people to not instantiate it. (No sane person can keep doing it.)
  2. Mark the utility class as abstract: Now robo-coders will not create the object. However, reviewers and the wider java community will argue that marking the class as abstract means you want someone to extend it. So, this is also not a good option.
  3. Private constructor: Not protected because it'll allow a child class to instantiate the object.

Now, if someone wants to add a new method for some functionality to the utility class, they don't need to extend it: they can add a new method as each method is independent and has no chance of breaking other functionalities. So, no need to override it. Also, you are not going to instantiate it, so no need to subclass it. Better to mark it final.

In summary, instantiating a utility class (new MyUtilityClass()) does not make sense. Hence the constructors should be private. And you never want to override or extend it, so mark it final.

Upvotes: 23

Recurse
Recurse

Reputation: 3585

There is an important distinction between the Java Language, and the Java Runtime.

When the java class is compiled to bytecode, there is no concept of access restriction, public, package, protected, private are equivalent. It is always possible via reflection or bytecode manipulation to invoke the private constructor, so the jvm cannot rely on that ability.

final on the other hand, is something that persists through to the bytecode, and the guarantees it provides can be used by javac to generate more efficient bytecode, and by the jvm to generate more efficient machine instructions.

Most of the optimisations this enabled are no longer relevant, as the jvm now applies the same optimisations to all classes that are monomorphic at runtime—and these were always the most important.

Upvotes: 0

Anselmo Battisti
Anselmo Battisti

Reputation: 1

By default this kind of class normally is used to aggregate functions who do different this, in that case we didn't need to create a new object

Upvotes: -2

Marko Topolnik
Marko Topolnik

Reputation: 200206

It's not necessary, but it is convenient. A utility class is just a namespace holder of related functions and is not meant to be instantiated or subclassed. So preventing instantiation and extension sends a correct message to the user of the class.

Upvotes: 12

Related Questions