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

5

20

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 ?

Shenika answered 3/9, 2015 at 12:4 Comment(5)
Why do you think it is mandatory? Do you have a reputable source that says it is necessary?Formicary
Think about what cannot you do with a class that's final and what you cannot with a class that has a private constructor.Leitmotif
@SubodhJoshi: now, in your own words, explain what you think making a class final changes to it.Impartial
Maybe the utility class just uses static methods so avoid people making instances of it. Making it finalwill protect you about being overridden.Wimsatt
My favorite part of this post is how my teammates told make final suddenly became Why is it necessaryFormicary
P
22

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.

Paediatrician answered 4/9, 2015 at 3:54 Comment(0)
O
11

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.

Omen answered 3/9, 2015 at 12:8 Comment(14)
Congratulations on 100k :)Leitmotif
So it mean its for only convenience nothing else ?Shenika
Yes. Nothing will break if you don't do it. Nothing huge will happen even if someone instantiates or extends it. The worst outcome would be confusing code, but that kind of error is not particularly likely.Omen
@SubodhJoshi: no. declaring it final means the methods can not be overridden. if your class would be subclassed, someone would be able to change the implementations. But mandatory, noImpartial
@Impartial There are no methods to override.Omen
@MarkoTopolnik: how do you know that? Have you seen his code?Impartial
@Impartial OP is either writing a utility class, or he isn't. He said he is and my answer pertains to that statement.Omen
@MarkoTopolnik: even though it would be weird to have instance methods in a Utility class, this is not impossible.Impartial
It is impossible to have instance methods in a Utility class. Much like it is impossible to have a private modifier on a public method.Omen
@Impartial If it has an instance method, it's not really a Utility class.Hyp
"So preventing instantiation and extension sends a correct message to the user of the class." It doesn't just "send a message", it outright forbid it. It's the equivalent of tying the developper's hands so they don't cut themselves with a knife. Wouldn't it better to simply warn the developer of the dangers, but let them do the instantiation/extension if they really need to?Skipjack
@GuillaumeF. In that spirit, would it also be better if Java didn't have the protected, private and final modifiers, as these are just restrictions? Maybe a comment about their usage would be better, and if you really want to access/modify something, you can?Omen
@MarkoTopolnik it depends on the perspective. For example, in Python, methods & attributes have a naming convention to indicate that the they are private and should most likely not be utilized from outside the class - but they do remain accessible to all. The philosophy of Python is that "We're all consenting adults here", and that developers should not be prevented from something just because it could be dangerous.Skipjack
@GuillaumeF. We seem to have at least three separate questions here: 1. What is the philosophy of Java? 2. Is there value in staying consistent with the language's philosophy? 3. What is your personal preference?Omen
C
1

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.

Crave answered 4/9, 2015 at 4:3 Comment(1)
Most of these statements are either wrong or don't apply to utility classes. 1. invokevirtual will fail if access restriction forbids it. 2. Bytecode of a reflective call doesn't even resemble a non-reflective call. 3. private has an effect on bytecode, as opposed to final (invokespecial can be used). Public final methods are called from the outside using invokevirtual. 4. final on a class has no effect on static method calls.Omen
S
0

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.

Skipjack answered 28/10, 2023 at 20:16 Comment(0)
C
-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

Cryoscopy answered 3/9, 2015 at 12:37 Comment(1)
Could you please elaborate more your answer adding a little more description about the solution you provide?Misbegotten

© 2022 - 2025 — McMap. All rights reserved.