5

I'm looking at this code of the correct way to do a singleton in java: What is an efficient way to implement a singleton pattern in Java?

I'm a little confused, how do you add a method to a enumeration?

 public enum Elvis {
       INSTANCE;
       private final String[] favoriteSongs =
           { "Hound Dog", "Heartbreak Hotel" };
       public void printFavorites() {
           System.out.println(Arrays.toString(favoriteSongs));
       }
   }

And the enumeration in the code above, doesn't even make sense to me, you have the symbol:

INSTANCE;

how is that a correct line?

I'm coming from c#, and this syntax got me curious and I'm hoping someone can explain or make sense of the above.

I guess it means java has a more purer idea of an enumeration as it can have behaviour?

Community
  • 1
  • 1
codecompleting
  • 9,251
  • 13
  • 61
  • 102
  • 2
    I'm not sure what the question is. – millimoose Oct 28 '11 at 21:34
  • If you're asking "why does that syntax work in Java?", it's because whoever designed enums in Java decided so. – millimoose Oct 28 '11 at 21:35
  • 3
    Btw, for some interpretations of "add a method to an enum", extension methods may help – Marc Gravell Oct 28 '11 at 21:37
  • Your example looks to me like a hackish Java workaround for the C# equivalent of a `struct`. Looking through the pages in the link you've provided, it looks like this is done for memory efficiency. But, one huge thing you have to consider is maintainability. In 3 years, is a developer going to look at that code and understand, or silent wish all the perils of the world on your head? – Joseph Yaduvanshi Oct 28 '11 at 21:37
  • @JimSchubert - using an enum as the basis for a singleton is java is pretty much the best way to do it. – Brian Roach Oct 28 '11 at 21:39
  • @Inerdia, No he/she is not asking it. He/she tries to understand `enum` in Java since it is much different than c# – L.B Oct 28 '11 at 21:41
  • 2
    @JimSchubert The example is of the "proper" way to implement a singleton object in Java. Using an `Enum` over a `Class` guarantees that only one instance will ever be created and since, in Java, an `Enum` is a `Class`, you can have all the same functions/variables you'd attach to that class. `Struct`s in C# are not, by default, singletons. It's just as maintainable as a class with proper documentation on the final produce and documenting the choice of `Enum` over `Class`. – Brandon Buck Oct 28 '11 at 21:44
  • @izuriel Thanks for clarifying that. I am also a C# developer who has only done a little in Java, so this difference isn't readily apparent. This also explains why some of the devs with Java backgrounds on my team think of C# `enum` types differently. – Joseph Yaduvanshi Oct 29 '11 at 20:02
  • @JimSchubert I started with Java and have used it extensively but currently work at a place that only uses C# so I've run into the differences quite often :P – Brandon Buck Oct 29 '11 at 20:41

3 Answers3

13

An enum in Java is actually a class. One that implicitly extends java.lang.Enum. The special syntax you see at INSTANCE; is a declaration of an enum constant. This is going to be used to make an instance of your enum class which can be referred to in code. As a matter of fact, you can even have a non-default constructor for your enum and use it in the constant declaration. Example:

public enum Test {

    INSTANCE("testing");

    private final String content;
    public Test(final String content) {
        super();
        this.content = content;
    }

}

Treating enums as true objects has certain advantages. Putting some logic into enums is convenient, but shouldn't be abused either. The singleton pattern via enums is a nice solution in my opinion, though.

G_H
  • 11,739
  • 3
  • 38
  • 82
  • 2
    That's a good clean answer there. In short, think of a Java enum type a as regular class, which can have fields, constructor and methods, but which simply comes with a predefined set of instances. – Shivan Dragon Oct 28 '11 at 21:45
  • @G_H is `INSTANCE` a special keyword in this situation, or can it be whatever you choose? – Joseph Yaduvanshi Oct 29 '11 at 20:04
  • @JimSchubert You can pick whatever name adheres to the Java language specs. It doesn't have a special meaning here. It's standard practice to use names in upper case for enums, though. `INSTANCE` isn't a keyword in Java, nor is it in lower case. `instanceof` is, so that wouldn't be usable. – G_H Oct 30 '11 at 03:05
1

You could use an extension method

enum Elvis
{
  Instance
}

static class ElvisExtension
{
  private static readonly string[] FavoriteSongs = { "Hound Dog", "Heartbreak Hotel" };

  public static void PrintFavorites(this Elvis singleton)
  {
    Console.WriteLine(string.Join(", ", FavoriteSongs));
  }
}

Usage:

Elvis.Instance.PrintFavorites();
Thomas Darimont
  • 1,356
  • 11
  • 14
1

To give a slightly different answer, and one that I think you're asking, the INSTANCE; line in the Java code is the equivalent line of Instance in the following C# example:

enum Elvis
{
    Instance
}

It's the way you create a value for a Java enum. To further the example a Java enum could be:

public enum Gender {
    MALE,
    FEMALE;
}

Where the value types are Gender.MALE and Gender.FEMALE which is equivalent to:

enum Gender
{
    Male,
    Female
}

in C#.

If I have veered far from your question I apologize.

Brandon Buck
  • 7,177
  • 2
  • 30
  • 51