67

So I looked into this "enum" type, and it kind of seems like a glorified array/ArrayList/List to me. What exactly is the use of it?

Maroun
  • 94,125
  • 30
  • 188
  • 241
ZimZim
  • 3,291
  • 10
  • 49
  • 67
  • 9
    In what way does it look like an array to you? You can't store things in it, you can't take things out of it, it doesn't contain anything... basically it has none of the properties one usually associates with arrays. – sepp2k Mar 24 '12 at 09:22
  • 4
    @sepp2k: Ah, I think I get it: the definition in the source code kinda looks like a list literal... – Michael Borgwardt Mar 24 '12 at 09:25
  • 1
    Linking to [another answer](http://stackoverflow.com/a/9289694/1108032) of mine, that some people found useful. I know it is in a thread comparing java enums and C++ enums, but I tried describing the java enum properties there. – Boris Strandjev Mar 24 '12 at 09:23
  • enum is not an array but say if your enum is MyEnum then MyEnum.values() is an array of all the constants within an enum – Ram Mandal Aug 19 '15 at 05:11

8 Answers8

71

Enum serves as a type of fixed number of constants and can be used at least for two things

constant

public enum Month {
    JANUARY, FEBRUARY, ...
}

This is much better than creating a bunch of integer constants.

creating a singleton

public enum Singleton {
    INSTANCE

   // init
};

You can do quite interesting things with enums, look at here

Also look at the official documentation

user219882
  • 15,274
  • 23
  • 93
  • 138
  • Those two things are pretty much the same thing. The singleton is also a 'constant', no? – aioobe Dec 18 '13 at 07:49
  • @aioobe look at this http://www.informit.com/articles/article.aspx?p=1216151&seqNum=3 – user219882 Dec 18 '13 at 15:37
  • 1
    @aioobe It shows you the way enum is used as a singleton. The first example (constant) is a fixed list of constants. This one on the other hand behaves more like a regular class but the Java itself ensures that this class is created only once. – user219882 Dec 18 '13 at 17:21
  • Ah, but you can just as well turn both arguments the other way around: A singleton is a fixed list of constants, and the `Month` enum is just as a regular class, except Java ensures that this class is only instantiated 12 times. You say *"can be used at least for two things"*, I say those two things are the same thing. :-) Wouldn't you agree? – aioobe Dec 18 '13 at 22:16
  • @aioobe No. Singleton is not a fixed list of constants. Singleton means that a particular object is instantiated only once. That's totally different situation. I think you are missing the point here. – user219882 Dec 19 '13 at 11:03
  • 2
    @Tomas I wouldn't say the [Singleton](http://en.wikipedia.org/wiki/Singleton_pattern) usage is "totally different". The programmer's intent may be different, as a Singleton often plays a bigger role in the app, while multi-value enums are usually some small specific detail. Perhaps that’s what you intended by your comment. But technically, the Singleton enum is just a "fixed list of constants" that happens have only one element. As aioobe asked, both examples in this Answer are, technically speaking, exactly the same thing; one is an enum with 12 values, the other with 1 value. – Basil Bourque Apr 12 '15 at 18:41
71

You use an enum instead of a class if the class should have a fixed enumerable number of instances.

Examples:

  • DayOfWeek  = 7 instances → enum
  • CardSuit    = 4 instances → enum
  • Singleton  = 1 instance   → enum

  • Product      = variable number of instances → class
  • User            = variable number of instances → class
  • Date            = variable number of instances → class
aioobe
  • 413,195
  • 112
  • 811
  • 826
46

An enumerated type is basically a data type that lets you describe each member of a type in a more readable and reliable way.

Here is a simple example to explain why:

Assuming you are writing a method that has something to do with seasons:

The int enum pattern

First, you declared some int static constants to represent each season.

public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int FALL = 2;
public static final int WINTER = 2;

Then, you declared a method to print name of the season into the console.

public void printSeason(int seasonCode) {
    String name = "";
    if (seasonCode == SPRING) {
        name = "Spring";
    }
    else if (seasonCode == SUMMER) {
        name = "Summer";
    }
    else if (seasonCode == FALL) {
        name = "Fall";
    }
    else if (seasonCode == WINTER) {
        name = "Winter";
    }
    System.out.println("It is " + name + " now!");
}

So, after that, you can print a season name like this.

printSeason(SPRING);
printSeason(WINTER);

This is a pretty common (but bad) way to do different things for different types of members in a class. However, since these code involves integers, so you can also call the method like this without any problems.

printSeason(0);
printSeason(1);

or even like this

printSeason(x - y);
printSeason(10000);

The compiler will not complain because these method calls are valid, and your printSeason method can still work.

But something is not right here. What does a season code of 10000 supposed to mean? What if x - y results in a negative number? When your method receives an input that has no meaning and is not supposed to be there, your program knows nothing about it.

You can fix this problem, for example, by adding an additional check.

...
else if (seasonCode == WINTER) {
    name = "Winter";
}
else {
    throw new IllegalArgumentException();
}
System.out.println(name);

Now the program will throw a RunTimeException when the season code is invalid. However, you still need to decide how you are going to handle the exception.

By the way, I am sure you noticed the code of FALL and WINTER are both 2, right?

You should get the idea now. This pattern is brittle. It makes you write condition checks everywhere. If you're making a game, and you want to add an extra season into your imaginary world, this pattern will make you go though all the methods that do things by season, and in most case you will forget some of them.

You might think class inheritance is a good idea for this case. But we just need some of them and no more.

That's when enum comes into play.


Use enum type

In Java, enum types are classes that export one instance for each enumeration constant via a public static final field.

Here you can declare four enumeration constants: SPRING, SUMMER, FALL, WINTER. Each has its own name.

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter");

    private String name;

    Season(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Now, back to the method.

public void printSeason(Season season) {
    System.out.println("It is " + season.getName() + " now!");
}

Instead of using int, you can now use Season as input. Instead of a condition check, you can tell Season to give you its name.

This is how you use this method now:

printSeason(Season.SPRING);
printSeason(Season.WINTER);
printSeason(Season.WHATEVER); <-- compile error

You will get a compile-time error when you use an incorrect input, and you're guaranteed to get a non-null singleton reference of Season as long as the program compiles.

When we need an additional season, we simply add another constant in Season and no more.

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter"), 
    MYSEASON("My Season");

...

Whenever you need a fixed set of constants, enum can be a good choice (but not always). It's a more readable, more reliable and more powerful solution.

Rangi Lin
  • 9,303
  • 6
  • 45
  • 71
28

An enum type is a type whose fields consist of a fixed set of constants. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time—for example, the choices on a menu, command line flags, and so on.

Here is some code that shows you how to use the Day enum defined above:

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

The output is:

Mondays are bad.
Midweek days are so-so.
Fridays are better.
Weekends are best.
Weekends are best.

Java programming language enum types are much more powerful than their counterparts in other languages. The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an enum type. For example, this code from the Planet class example below iterates over all the planets in the solar system.

for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

In addition to its properties and constructor, Planet has methods that allow you to retrieve the surface gravity and weight of an object on each planet. Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

If you run Planet.class from the command line with an argument of 175, you get this output:

$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413

Source: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

Ashraf Bashir
  • 9,686
  • 15
  • 57
  • 82
  • 16
    You could at least write a source since you copy-pasted the official documentation without a change. – user219882 Mar 24 '12 at 09:39
  • Calm down guys, I just was focusing on helping him no more than that ! link of source is now attached !!!!! – Ashraf Bashir Mar 24 '12 at 09:42
  • 1
    To be honest, that text starts with a quite misleading statement. An enum can have more fields than just a set of constants. – aioobe Mar 24 '12 at 09:46
  • Yup, you are right it may be so, but if you continue reading you will find more description about enum that can clarify its use in details. – Ashraf Bashir Mar 24 '12 at 09:49
2

an Enum is a safe-type so you can't assign a new value at the runtime. Moreover you can use it in a switch statement (like an int).

Guillaume USE
  • 436
  • 1
  • 4
  • 6
  • 1
    I don't get this answer. Ordinary classes are also type-safe. If you're comparing it to using integers, then why highlight the fact that you can use them in a switch?! – aioobe Mar 24 '12 at 09:44
  • It's more elegant to use a Enum in a switch than an Integer. – Guillaume USE Mar 24 '12 at 09:51
  • Why do you say that? (I would say it's more elegant to use an enum than an int, and you don't have to *sacrifice* the switch statements.) – aioobe Mar 24 '12 at 09:54
  • 1
    switch(i) { ... case 11: delete(); break; ... } switch(actions) { ... case DELETE: delete(); break; ... } Which code is the cleanest ? the Enum, isn't it ? – Guillaume USE Mar 24 '12 at 10:00
  • 1
    Don't you use *named* constants, like public static int DELETE = 11 in your code? (For those who do, the switch statements look the same as in the enum case.) – aioobe Mar 24 '12 at 19:07
  • 2
    If you're using an enum in a switch, you're doing it wrong - invert it so that the code is *in the enum*. enum.doThings(stuff) is a lot easier to read than switch(enum) { case THING1: { } case THING2: {} } - it also cuts down on cyclomatic complexity, which makes it easier to read and test the code. – MetroidFan2002 Mar 05 '13 at 21:56
0

Enums are the recommended way to provide easy-to-remember names for a defined set of contants (optionally with some limited behaviour too).

You should use enums where otherwise you would use multiple static integer constants (eg. public static int ROLE_ADMIN = 0 or BLOOD_TYPE_AB = 2)

The main advantages of using enums instead of these are type safety, compile type warnings/errors when trying to use wrong values and providing a namespace for related "constants". Additionally they are easier to use within an IDE since it helps code completion too.

xea
  • 1,204
  • 12
  • 23
0

Java programming language enums are far more powerful than their counterparts in other languages, which are little more than glorified integers. The new enum declaration defines a full-fledged class (dubbed an enum type). In addition to solving all the problems(Not typesafe, No namespace, Brittleness and Printed values are uninformative) that exists with following int Enum pattern which was used prior to java 5.0 :

public static final int SEASON_WINTER = 0;

it also allows you to add arbitrary methods and fields to an enum type, to implement arbitrary interfaces, and more. Enum types provide high-quality implementations of all the Object methods. They are Comparable and Serializable, and the serial form is designed to withstand arbitrary changes in the enum type. You can also use Enum in switch case.

Read the full article on Java Enums http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html for more details.

Kuldeep Jain
  • 8,409
  • 8
  • 48
  • 73
-7

1) enum is a keyword in Object oriented method.

2) It is used to write the code in a Single line, That's it not more than that.

     public class NAME
     {
        public static final String THUNNE = "";
        public static final String SHAATA = ""; 
        public static final String THULLU = ""; 
     }

-------This can be replaced by--------

  enum NAME{THUNNE, SHAATA, THULLU}

3) Most of the developers do not use enum keyword, it is just a alternative method..

GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
Naveen AH
  • 23
  • 5