7

When the Gang of four introduced the singleton pattern, they also had to explain, why not to use static class fields and method instead. The reason was: the possibility to inherit. For Java it had sense - we cannot normally inherit the class fields and methods.

Later the "Effective Java" book appeared. And we know now that the existence of reflection destroys the singularity of the singleton class with private constructor. And the only way to make a real SINGLEton is to make it as a single item of an enumeration. Nice. I had done some myself this way.

But a question remains: While we cannot inherit from enumeration, what is the use of this singleton? Why we don't use these old good static/class fields and methods?

Edit. Thanks to the @bayou.io I see that in https://softwareengineering.stackexchange.com/a/204181/44104 there is a code that can trick the enum, too, and create again two exemplars of the enum singleton. The other problems are mentioned there, too. So, there is no need to use enum instead of the usual singleton class pattern, too? BTW, all enum pluses that are mentioned here till now, work for singleton classes, too.

Community
  • 1
  • 1
Gangnus
  • 24,044
  • 16
  • 90
  • 149
  • 3
    I don't think this question is really a duplicate of that question. It's not about how or why to implement a singleton object with an Enum. It's about why to implement an object (instance) at all instead of having all the singleton's functionality written with static methods and accessed by class name instead of object reference. – RealSkeptic Oct 02 '15 at 18:55
  • Fair enough, that concept is so alien to me, I didn't even consider it. – Sotirios Delimanolis Oct 02 '15 at 19:01
  • That another question only has a common word - singleton. That is all. – Gangnus Oct 02 '15 at 19:13
  • http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing-a-singleton-with-javas-enum – ZhongYu Oct 02 '15 at 19:51
  • The ability to inherit from an interface is not available in classes, so your new edit is incorrect. – RealSkeptic Oct 02 '15 at 20:41
  • @RealSkeptic there is not and there was not a word about interfaces neither here or on Programmers', thank God. The subject we are having is enough complicated already. – Gangnus Oct 02 '15 at 20:49
  • Well, the only proper answer you got to your question below was the one that said that objects (including enums) can implement interfaces, and thus you can pass them around as those interfaces. This can't be done by static classes. Other than that, you either got answers that were not about your question, or got confused into thinking that enums can inherit from classes. The "pollution" question and whether an enum is better than a plain object (not a class) is a different question. – RealSkeptic Oct 02 '15 at 20:51
  • @RealSkeptic And what do you think about the possibility of making the thread safe lazy instantiation? It is not in answers though. – Gangnus Oct 02 '15 at 21:02
  • Again, you can't lazy instantiate a *static* class. And you can't lazy instantiate an enum. So there is no difference between them there. I think you are now mixing your original question with new ones. There seem to be three options: (1) Singleton **instance** using a traditional class. (2) Singleton **instance** using an enum. (3) Singleton functionality using static variables and methods. Originally you asked whether (3) is better than (2) - the question whether (2) is better than (1) has been discussed lots of times in SO, Programmers etc. – RealSkeptic Oct 02 '15 at 21:06
  • I'm getting confused with your discussions guys. @RealSkeptic what do you mean saying this can't be done with a static class ? Of course a static class can implement interfaces. There's nothing an enum can do that a plain class cannot do, since an enum is just a particular kind of class. – Dici Oct 02 '15 at 21:06
  • @RealSkeptic A class is loaded when it's used. It's by definition lazy. Same for an enum. If it's never used during all the execution, it will never be loaded – Dici Oct 02 '15 at 21:08
  • @RealSkeptic Yes, correctly, I have started to compare 1 and 2. But now I see that there is no need to use enum singletons at all. Anyway, they are not more safe. – Gangnus Oct 02 '15 at 21:09
  • When it's mentioned, not when it's used, @Dici. If your first mention of it is `ClassName.class.getClassLoader()` for example, your instance will be initialized. – RealSkeptic Oct 02 '15 at 21:12
  • @Dici The problem is that I wanted to know what good is in enum singleton, and I have found what terrible heaps of bad are in it. I am wiser a bit, but my question seems incorrect for me now. – Gangnus Oct 02 '15 at 21:14
  • @RealSkeptic so you are talking about the singleton instance, not the class itself. Well, it's easy to make the instance lazy, using a static method instead of directly referring to the static field – Dici Oct 02 '15 at 21:16
  • It was a cool gimmick when `enum` first came out. There's no real good reasons. But probably not too bad either. – ZhongYu Oct 02 '15 at 21:19
  • @RealSkeptic Could you make an answer of this thought about inheritance from interfaces, please, I 'd mark it as the answer. – Gangnus Oct 03 '15 at 14:18
  • @Gangnus the interface inheritance is already in the answer by dkzatel. – RealSkeptic Oct 03 '15 at 16:08

4 Answers4

3

what is the use of this singleton? Why we don't use these old good static/class fields and methods?

Because enum is an object so it can not only be passed around but also implement interfaces.

Also since we are making a class, we can use the different public/private options available to all kinds of classes.

So in practice, we can make a singleton that implements an interface and then pass it around in our code and the calling code is non the wiser. We can also make the enum class package private but still pass it around to other classes in other packages that expect the interface.

If we used the static methods version, then the calling class would have to know that this object is a singleton, and our singleton class would have to be public so the other classes can see it and use it's methods.

dkatzel
  • 31,188
  • 3
  • 63
  • 67
2

There's nothing particularly wrong with the "good old fashioned singleton", enum "singletons" are just convenient - it saves you the need to muck around with boiler-plated code that looks the same in every singelton.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • You haven't even tried to answer the question - what is the use of enum singleton insted of class fields/methods? – Gangnus Oct 02 '15 at 18:50
1

To me, a singleton makes sense wherever you want to represent something which is unique in its kind.

As an example, if we wanted to model the Sun, it could not be a normal class, because there is only one Sun. However it makes sense to make it inherit from a Star class. In this case I would opt for a static instance, with a static getter.

To clarify, here is what I'm talking about :

public class Star {
    private final String name;
    private final double density, massInKg;  

    public Star(String name, double density, double massInKg) {
        // ...
    }

    public void explode() {
       // ...
    }
}

public final class Sun extends Star {
    public static final Sun INSTANCE = new Sun();

    private Sun() { super("The shiniest of all", /**...**/, /**...**/); }
}

Sun can use all the methods of Star and define new ones. This would not be possible with an enum (extending a class, I mean).

If there is no need to model this kind of inheritance relationships, as you said, the enum becomes better suited, or at least easier and clearer. For example, if an application has a single ApplicationContext per JVM, it makes sense to have it as a singleton and it usually doesn't require to inherit from anything or to be extendable. I would then use an enum.

Note that in some languages such as Scala, there is a special keyword for singletons (object) which not only enables to easily define singletons but also completely replaces the notion of static method or field.

Dici
  • 25,226
  • 7
  • 41
  • 82
  • So, it is useful, for even if it cannot be inherited from, it can inherit itself, and it is very convenient in most cases. yes. It is a reason, too, apart from thread safety. – Gangnus Oct 02 '15 at 18:56
  • It's not "cleaner" :) Polluting your type with a Enum superclass is not good. – ZhongYu Oct 02 '15 at 19:56
  • What do you mean ? In both case you refer to your singleton using `SingletonName.INSTANCE` and in both case you can static import it... What pollution are you talking about ? – Dici Oct 02 '15 at 20:00
  • Polluting or not... this was not the question. The question was why implement it as an object in the first place. – RealSkeptic Oct 02 '15 at 20:02
  • You mean as a class ? And I believe I answered it. – Dici Oct 02 '15 at 20:03
  • Yes, as a class with its functionality expressed as static state and static methods, and instead of accessing the singleton through an object reference, access it through the class name. I believe you were referring to a static instance, but the question is about a static class. – RealSkeptic Oct 02 '15 at 20:06
  • @RealSkeptic But I can see the answer here - the use of inheritance for enum creation is a good reason. But it should be put in the text more distinctly, I agree. – Gangnus Oct 02 '15 at 20:31
  • @Gangnus I think you misread this one. He said that if you *don't* need inheritance, using enum is good. If you need inheritance, neither using a class nor using an enum will work (unless it's an inheritance of type, using an interface, where enum has an advantage, but this is not discussed here). – RealSkeptic Oct 02 '15 at 20:36
  • Mmmm I need to rework this, I also misread the question. I was thinking about implementing something similar to the `object` keyword in Scala. Enums cannot inherit from an abstract class, for example, whereas what I'm talking about can. Nevertheless it seems I misunderstood the question – Dici Oct 02 '15 at 20:43
  • @RealSkeptic Not for inherit from enum, but to use inheritance to create enum on the base of other classes. We can't do it basing on the class fields/methods. Yes, he didn't said it directly, but the thought is there ("it makes sense to make it inherit from a Star class") BTW, nobody said it directly in an answer. The same about the possibility of synchronization :-( – Gangnus Oct 02 '15 at 20:44
  • @Gangnus You can't base an enum on another class. You can't write `extends` as it already extends the `Enum` cluss. – RealSkeptic Oct 02 '15 at 20:46
  • Edited to clarify my thoughts – Dici Oct 02 '15 at 20:53
  • @Dici You are right. You have shown how good is the class for a singleton. And I am starting to believe that singleton really is NOT good for it. I have plused your answer at once, now it is definitely better, but alas, it is not THE ANSWER yet, sorry. I hope, you see it, too. – Gangnus Oct 02 '15 at 20:58
0
  1. ENUM singletons are easy to write. It will occupy very less code, which is clean & elegant if you compare with implementation of lazy singleton with double synchronized blocks

     public enum EasySingleton{
        INSTANCE;
    }
    
  2. Creation of ENUM instance is thread safe.

  3. ENUM singletons handled serialization by themselves.

    conventional Singletons implementing Serializable interface are no longer remain Singleton because readObject() method always return a new instance just like constructor in Java. you can avoid that by using readResolve() method and discarding newly created instance by replacing with Singeton

    private Object readResolve(){
        return INSTANCE;
    }
    

Have a look at this article on singleton

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • 2
    OP is trying to differentiate between a singleton type implemented with an object and a singleton type which doesnt expose an object and instead is implemented solely through static method and fields. – Sotirios Delimanolis Oct 02 '15 at 19:38
  • Enum is thread safe only if you create the instance from the start. In the case of lazy instantiation you should do it yourself - so, it can be made thread safe, but beware - you should pay your own attention to it. – Gangnus Oct 02 '15 at 20:27
  • I have answered for OP's query : what is the use of enum singleton insted of class fields/methods in response to Mureinik answer – Ravindra babu Oct 02 '15 at 20:27
  • Personally I hate lazy initialization of singleton. We know that singleton object is required and I did not see merit in delaying construction with complicated double locking – Ravindra babu Oct 02 '15 at 20:29
  • I can see it :-). But anyway, instead of "is" it would be better to say "can be made". And your #2 point becomes precise. – Gangnus Oct 02 '15 at 20:46