In Java, the enum is a reference type (don't let that little 'e' fool you). You can do neat things with it like define methods. A classic example of that is the Operation
enum being defined as:
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
//Elsewhere:
Operation op = Operation.PLUS;
double two = op.eval(1, 1);
And you can see... yep, it has methods and so its not a primitive. They are Objects.
There is also some magic that happens in the compiler as described in the Java Enum Tutorial:
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.
And I'll certainly agree that its annoying that this isn't mentioned in the javadocs.
The values that are returned from the values()
call is an array that one can then iterate over.
class Demo {
enum DayOfWeek {
U, M, T, W, R, F, S
}
public static void main (String[] args) {
for (DayOfWeek day : DayOfWeek.values()) {
System.out.println(day.toString());
}
}
}
This prints out:
U
M
T
W
R
F
S
Run this code at ideone
Why no next? Well, given the ability to get the values()
array it fills all the use cases for the next()
method and is a bit more powerful.
If you really do want the next()
method it takes takes a little bit of a hoop to get the array into an Iterator
object (which is itself a replacement for the Enumeration type - see the javadoc):
import java.util.*;
class Demo {
enum DayOfWeek {
U, M, T, W, R, F, S
}
public static void main (String[] args) {
Iterator days = Arrays.asList(DayOfWeek.values()).iterator();
while(days.hasNext()) {
System.out.println(days.next());
}
}
}
Run this code at ideone
So again, the reason that its not there is that its not needed. You can get an array back from the enum quite easily and iterate over that, or convert that array into an Iterator
allowing you to call next()
.
There is also possibly the confusion that would be had trying to make the enum
and Enumeration
look too similar (they already look too similar) and trying to make the enum
look more like the Enumeration
with the same method calls would further confuse things. That said, this is just speculation.
Fundamentally, the Java enum
is much like the C enum
with the ability to have some methods on the side. Its a bit more constrained you can't have them be specific numbers behind the scenes as you can in C:
/* This is C */
enum cardsuit {
CLUBS = 1,
DIAMONDS = 2,
HEARTS = 4,
SPADES = 8
};
People sometimes point to Pascal and say succ
can be called on an enum there, why not in Java? Pascal enums are ordinal types while C enums are not. Java borrows from C rather than Pascal.
There's nothing saying that you can't define your own next()
or prev()
function. Its rather easy to do after getting around an annoyance of forward references.
class Demo {
enum DayOfWeek {
U, M, T, W, R, F, S;
private DayOfWeek n;
private DayOfWeek p;
static {
U.n = M; U.p = S;
M.n = T; M.p = U;
T.n = W; T.p = M;
W.n = R; W.p = T;
R.n = F; R.p = W;
F.n = S; F.p = R;
S.n = U; S.p = F;
}
public DayOfWeek next() { return this.n; }
public DayOfWeek prev() { return this.p; }
}
public static void main (String[] args) {
System.out.println(DayOfWeek.M.next());
System.out.println(DayOfWeek.U.prev());
}
}
T
S
So...
- The enum was borrowed from the C tradition of an enum, not the Pascal tradition of ordinal types
- They didn't want to confuse
enum
with Enumeration
- You have the ability to get all the values back easily with an iterable type
- You can define a
next()
method that works any way you want it to.
next
operation would be sufficient (or even applicable) in most cases. Perhaps it's been applicable to in most of your cases so far, but keep in mind that software (and enums) can model any number of abstract concepts. This one comes to mind thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx.next
function, but that'd require even more work on their part, and it's kind of a slipper slope; you could keep asking for more and more features until they have to add full algebraic data types to the language.