What are java enums? How do they work? Where could I used them and how?
Can I do without using enums in an app or are they so powerful that Its better to use them than i
Enums in Java 5+ are basically classes that have a predefined set of instances. They are intended as a replacement for, say, a collection of integer constants. They are preferably to constants as they can enforce type safety.
So instead of:
public class Suit {
public final static int SPADES = 1;
public final static int CLUBS = 2
public final static int HEARTS = 3;
public final static int DIAMONDS = 4;
}
you have:
public enum Suit {
SPADES, CLUBS, HEARTS, DIAMONDS
}
The advantages are:
The type safety is an issue because in the first example, these are valid statements:
int i = Suit.DIAMONDS * Suit.CLUBS;
or you can pass in 11 to a function expecting a suit. You can't do that with a typesafe enum.
You can use a class for Suit to provide type safety and this was the solution before Java 5. Josh Bloch (in Effective Java, which is a must read for Java programmers imho) promoted the typesafe enum pattern that became the Java 5+ enum. It has a fair amount of boilerplate on it and some corner cases that people didn't tend to cater for, such as serialization not calling a constructor and to ensure you only got one instance you had to override the readResolve() method.
For example:
public enum CardColour {
RED, BLACK
}
public enum Suit {
SPADES(CardColour.BLACK),
CLUBS(CardColour.BLACK),
HEARTS(CardColour.RED),
DIAMONDS(CardColour.RED);
private final CardColour colour;
Suit(CardColour colour) { this.colour = colour; }
public CardColour getColour() { return colour; }
}
Edit: Sun has an introduction to typesafe enums.
As for interfaces, they really complement enums rather than being an alternative. Like you could say that Suit is an interface and you'd have this:
public interface Suit {
CardColour getColour();
}
The problem is that you could go and define 300 different suits and you could also define Spades several times. Another advantage of enums is (classloading corner cases notwithstanding) is that there is only one instance of each enum value. Typically this is referred to as having a canonical value, meaning this equality holds true:
a.equals(b) == b.equals(a) == (a == b)
for all a, b that are instances of a particular Enum. This means that instead of writing:
if (card.getSuit().equals(Suit.SPADES)) { ... }
you can write:
if (card.getSuit() == Suit.SPADES) { ... }
which is quicker and typically easier to read. Plus IDEs will typically give you feedback if you're comparing enums of different types saying they can't possibly be equal, which can be a useful and early form of error-checking.
Sun's enum documentation is probably the best explanation. Of course you can do without them as Java programmers certainly did until Java 1.5 was released. You would typically accomplish the same thing by using constants in versions of Java before 1.5. But enums are a nice convenience.
Think of Enum as follows
public class MyEnum {
// Object instantiated at declaration
public static final MyEnum ONE = new MyEnum();
public static final MyEnum TWO = new MyEnum();
public static final MyEnum THREE = new MyEnum();
// Notice a private constructor
// There is no way outside MyEnum class call it
private MyEnum() { ... }
}
So a MyEnum as a enum would be
public enum MyEnum {
ONE,
TWO,
THREE;
}
Both are similar
regards,
To add some additional information to find out it more, it is better to start with concept of a variable and its values. As I am sure you now, each variable has a declared type (such as Java primitive types). Each type has its own corresponding values. For example a variables with the char type can accept all individual characters as its values. So it is very helpful when you want to declare a variable can accept all set of character constants. For instance all character constants are acceptable and meaningful for aCharToStopProgram variable:
char aCharToStopProgram = getUserInput();
However, what about when you have a limited value, I mean value's domain of your variable is restricted to special values. For example you have userChoice which keeps value of system multiple choice question. So just 'a', 'b', 'c', 'd' is meaningful. You don't want in another section of your program code(or any other reason) this variable is assigned with meaningless values such as 's'. Now is it true to use a char primitive type for our variable which can accept any character constant, such following.
char userChoice = getUserChoice();
In this situations Java provides Enumerated Types. It means via enum keyword you can define a new class that has limited and fixed instances which is call named values(you can not creat new objects). For example:
enum MultipleChoiceAnswer { A, B, C, D };
or
public enum MultipleChoiceAnswer {
A('a'), B('b'), C('c'), D('d');
private char choice;
private MultipleChoiceAnswer(char choice) {
this.choice = choice;
}
public String getChoice() {
return choice;
}
}
As result you can define a variable with your own type:
MultipleChoiceAnswer userChoice = getUserChoice();//OR MultipleChoiceAnswer.A
If the situation doesn't come up then you don't need them.
They allow you to have a well defined set of things, for instance if you wanted to represent the states of matter you could have:
enum MatterState {
Solid,
Liquid,
Gas;
}
Where they beat the old style of using objects to represent sets in a number of ways, some of which are:
From my interpretation, enums are more for readability than anything else. They are basically used to replace values like 1-6 with more descriptive names, like [Happy, Sad, Angry, etc] You should use them whenever you need to use a small set of variables to describe the solution that you are expecting.