Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zero instance enum vs private constructors for preventing instantiation [closed]

Tags:

java

enums

Some utility classes (think java.lang.Math) declares only a private constructor in order to prevent instantiation of the class.

Is there any particular reason for why such classes are not implemented in terms of a 0-instance enum? It seems to me like enums is a more direct way of controlling instantiation than access modifiers on constructors. It also prevents the class itself from creating instances which both prevent the programmer from shooting himself in the foot and convey a guarantee outwards of no instances.

Joshua Bloch advocates the use of enums for singletons. Shouldn't the same benefits apply to 0-instance utility classes?

My question: What are the pros/cons of 0-instance enums vs private constructors. (I personally see no drawbacks of using an enum, though private constructors seems to be the more prevalent approach.)

(I know java.lang.Math predates enum. I'm talking 1.5+ code here.)

like image 872
aioobe Avatar asked Aug 05 '14 11:08

aioobe


People also ask

Should enum constructor be private?

The enum constructor must be private . You cannot use public or protected constructors for a Java enum . If you do not specify an access modifier the enum constructor it will be implicitly private .

Does an enum need a constructor?

We need the enum constructor to be private because enums define a finite set of values (SMALL, MEDIUM, LARGE). If the constructor was public, people could potentially create more value. (for example, invalid/undeclared values such as ANYSIZE, YOURSIZE, etc.). Enum in Java contains fixed constant values.

What's the difference between an enum's constructor and a regular class constructor?

An enum can, just like a class , have attributes and methods. The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden). An enum cannot be used to create objects, and it cannot extend other classes (but it can implement interfaces).

Are enum constructors private by default?

Enum cannot have a default no-argument constructor and all its constructors (if any) are private; therefore, it is redundant to specify them explicitly. Note that the enum constructor classes are implicit and do not require new keyword.


2 Answers

The fact that enums cannot be instantiated is a side-effect. When you declare something as an enum, people would expect it to be an enum; it will appear as enum in the IDE, code analysis tools, whatever.

Following the principle of least astonishment, and given that the user doesn't care of how you internally achieve that, I think it's better to use a private constructor, and also throw an Error from that constructor, provided someone tries to instantiate it with reflection.

like image 87
Bozho Avatar answered Sep 18 '22 12:09

Bozho


So, to summarize the answers and comments so far:

Arguments supporting 0-instance enums:

  • Enum solves the problem of controlling instantiation of classes which is precisely what a 0-instance utility class needs.

  • Weekday has 7 instances, Month have 12, MySingleton has 1 (and should according to Joshua Bloch be implemented by means of an enum) and MyUtilityClass has 0 instances. There is no conceptual difference between the last case and the former ones.

  • A 0-instance enum guarantees that no instance will be created, not even from within the class itself.

Arguments against 0-instance enums:

  • Does not follow the principle of least astonishment; when people see an enum, they expect it to follow the text-book examples of non-empty enums such as weekdays, status codes etc.

  • The 0-instance enum is an idiom not widely used and thus not something other programmers recognize easily. I.e. it's less readable than using private constructors.

  • Enums are cluttered with implicit synthetic methods, which means that those names are not allowed for custom-defined methods. Furthermore, the fact that a public API exposes methods which should not be used can range from awkward to broken.

Other notes

  • Related question and answer.

  • Blog post on the subject by Peter Lawrey.

like image 44
7 revs, 3 users 82% Avatar answered Sep 19 '22 12:09

7 revs, 3 users 82%