Every enum has an ordinal
, so it is valid to get the "next" value for all enums - not just those you are trying to use a base class for. This means you can write the following helper method:
public static <T extends Enum<T>> T getNext(T current) {
Class<T> enumType = current.getDeclaringClass();
T[] enumConstants = enumType.getEnumConstants(); // Similar to e.g. Day.values()
int currentOrdinal = current.ordinal();
int nextOrdinal = currentOrdinal + 1;
if (nextOrdinal == enumConstants.length) { // Handle wrapping around to the beginning of the enum values
nextOrdinal = 0;
}
return enumConstants[nextOrdinal];
}
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public enum Month {
JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
}
public static void main(String... args) {
System.out.println(getNext(Day.MONDAY)); // TUESDAY
System.out.println(getNext(Day.SUNDAY)); // MONDAY
System.out.println(getNext(Month.JANUARY)); // FEBRUARY
System.out.println(getNext(Month.DECEMBER)); // JANUARY
}
If you really want to not be able to do this for all enums (perhaps it doesn't make sense for an enum that is not strictly ordered), then you can apply a marker interface, like so:
public interface Ordered {}
public enum Day implements Ordered {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public static <T extends Enum<T> & Ordered> T getNext(T current) {
...
}
You can find some more details about reflectively working with enums here.