1

When is a singleton class preferred over a class that has only static methods and a private default constructor?

Please vote.

H2ONaCl
  • 10,644
  • 14
  • 70
  • 114
  • You can have an instance of the singleton, whereas your other class wouldn't be instantiable. – NullUserException Sep 21 '11 at 01:21
  • possible duplicate of [static class vs singleton class](http://stackoverflow.com/questions/6092631/static-class-vs-singleton-class) – Joe Sep 21 '11 at 01:21
  • 1
    @Joe Not a duplicate. Only inner classes can be `static` in Java, so that really has nothing to with the question. – NullUserException Sep 21 '11 at 01:24
  • Why is it close-voted? Please explain. If I preface every question with "what is the best-practice in regard to" then every opinion question becomes a fact question. It doesn't change the nature of the question. – H2ONaCl Sep 21 '11 at 01:58

6 Answers6

5

When is a singleton class preferred over a class that has only static methods and a private default constructor?

When you need an instance. For example, to pass as method argument.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • You mean to restrict access to only objects that receive a copy of the reference? That doesn't seem like a big concern because the singleton should only be used for system wide resources. If it's system wide, a little privacy is great but not of tremendous value I think. I wonder if that is the only reason to prefer the singleton. – H2ONaCl Sep 21 '11 at 02:10
  • That's also why singletons are so rarely used and hated in proper OO. – BalusC Sep 21 '11 at 02:11
5

Use a singleton to better control when initialization occurs. With a static class, any initialization must be at class load-time, which you have little control over. For example, a simple reference to a static final MEMBER will trigger class loading. With a singleton, initialization can trivially be deferred till much later - typically, till first time of use.

Reasons to delay initialization may be:

  • it's expensive and you don't always need it for that class
  • you can't initialize till some other resource is initialized (say, a database connection). In this case, a lazily-instantiated singleton often provides correct order of operations without any explicit control - if it's not referenced till after the other resource is initialized, everything happens for free.

Use a singleton to improve testability. If you need to make some kind of mock object (in the broad sense) of the singleton in order to test its clients, one way to do it is to put an interface on its use, and supply a test singleton that's of a different class but implements the same interface.

Using a singleton makes initialization testing easier as well.

Use a singleton when you might need to debug initialization. Stack traces from static initialization can be puzzling. Debugging can be puzzling too. If the class is loaded early, it may break before a breakpoint on the first line in main() is even hit.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
1

If you have some state you need to store, a singleton is the way to go. For instance, if your class needs to load some configuration from a properties file.

dbyrne
  • 59,111
  • 13
  • 86
  • 103
  • 1
    Static fields accessed by static methods can also store state even if you cannot instantiate the class. It might or might not be obvious but you can write a small class to prove it. – H2ONaCl Sep 21 '11 at 01:35
  • 1
    @broiyan Its certainly possible, but not necessarily advisable. Lets take the example I gave: loading a properties file. It might be confusing for users of your class who don't understand that they need to call a static method to set the properties file before they can start using the other methods. In a singleton, where the properties file is loaded when the instance is created, the user doesn't have a chance to make this mistake. – dbyrne Sep 21 '11 at 01:47
  • In an utility class, that method can just be called in a static initializer. See also for example http://stackoverflow.com/questions/2027244/what-is-the-best-way-to-initialize-a-complex-static-member-in-java and http://stackoverflow.com/questions/4362911/how-to-create-a-singleton-class – BalusC Sep 21 '11 at 01:50
  • @broiyan Put another way, the singleton can still be immutable even though its accepting some initial state. If you are mutating static fields via static methods, this isn't the case. – dbyrne Sep 21 '11 at 01:51
  • @BalusC If the location of the properties file isn't known until runtime, using a static initializer isn't the most elegant solution in my opinion. – dbyrne Sep 21 '11 at 01:57
  • It was also just an example :) This is generally to be used for internal use only. And properties files are usually to be placed right in the classpath so that you don't need to pass some disk file system path along. – BalusC Sep 21 '11 at 01:59
1

The main reason for only having static methods is when you just need a toolbox to pack some functions together.

I use singletons for mainly two reasons:

  1. It is really expensive (time or memory) to construct the object, and I want to only ever do it once.
  2. The data associated with the class needs to be the same in every instance of the class.
regality
  • 6,496
  • 6
  • 29
  • 26
  • Valid points but you can build an expensive object in static methods and store it in static fields. There will be only one copy. – H2ONaCl Sep 21 '11 at 01:54
0

Static method is not dynamic, this is a big different with singleton class instance. So if you need to extends from a class and override some method, the second way won't work.

And the for the second way, you may need to use some static references which may lead to memory leak.

DeepNightTwo
  • 4,809
  • 8
  • 46
  • 60
0

I would say that a singleton class would be preferred only in one case: when you have some configuration to store that is system wide, will rarely (if ever) need to be refreshed.

As an example of what I mean, I have a singleton pattern in one of my applications that represents the NAT device of the user's internet connection. This application is intended for desktop use, and so would rarely (if ever) see a change in the internet connection. Presumably the user could carry their laptop to a new location, and this would change; however, there is a method to recreate the state in this event, but this is very infrequently changed state that can take several seconds to initialize.

This need to keep expensive, infrequently changing, and globally applicable state is best done by either an application scoped bean (my preferred option) or a singleton pattern bean. Static methods aren't as good for preserving this kind of state, though you could also accomplish this using static fields as well to make a pseudo-singleton. (Not sure if there's a better name for this - probably)

In general, my recommendation is not to use singleton like patterns if you can avoid it, as it makes re-use more difficult. If you're using a CDI framework, scope your bean at the application level for easier re-use. (This may not be a concern of yours - if not, you may safely ignore this advice)

SplinterReality
  • 3,400
  • 1
  • 23
  • 45
  • It's a matter of opinion mostly, but I personally never put anything that will change at any point in the future into a static field. (especially a public static field) My reasoning for this is that it essentially creates a global variable, and makes it entirely too easy to end up with disparate pieces of code that overwrite the same data, causing real headaches to diagnose bugs when they pop up. See http://c2.com/cgi/wiki?GlobalVariablesAreBad – SplinterReality Sep 21 '11 at 02:53