If you are always in awe of the simple yet powerful Enums in java, follow along ;)
In Java, enum
data type internally inherits from java.lang.Enum
class.
Use cases to consider:
- should have methods
name(), ordinal()
asfinal
which no one can override - always maintain singleton status for each enum value
- you shouldn't be able to access enum constructor (make it private)
- should have ordinal (consider sequential numbering idea)
- the enum should have a
values()
which returns all enum values.
I wrote a simple yet fairly complete implementation, so I welcome any feedback.
import java.util.List;
abstract class EnumBase implements Comparable<EnumBase>, Serializable {
private final int ordinal;
private final String name;
protected EnumBase(int ordinal, String name) {
this.ordinal = ordinal;
this.name = name;
}
public final int ordinal() {
return ordinal;
}
/**
* non overridable
*
* @return always gives ENUM Constant name
*/
public final String name() {
return name;
}
/**
* It is desired to be overloaded
*
* @return default to enum constant name
*/
@Override
public String toString() {
return name;
}
@Override
public final boolean equals(Object o) {
return o == this; // as singleton always yield true
}
@Override
public final int hashCode() {
return super.hashCode(); // don't need it as there can only be ONE instance on an Enum
}
@Override
public final int compareTo(EnumBase o) {
return Integer.compare(o.ordinal, ordinal);
}
/**
* This guarantees that enums are never cloned, which is necessary
* to preserve their "singleton" status.
*/
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/**
* prevent default deserialization
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}
public class MyEnum {
private static int ordinalCounter = 0;
/**
* Utility class where we fix the ordinal as sequential integers
*/
private abstract static class AbstractEnum extends EnumBase {
private AbstractEnum(String name) {
super(++ordinalCounter, name);
}
}
// singleton instance
public static final FIRST FIRST = new FIRST();
static class FIRST extends AbstractEnum {
private FIRST() {
super(FIRST.class.getSimpleName());
}
}
public static final SECOND SECOND = new SECOND();
static class SECOND extends AbstractEnum {
private SECOND() {
super(SECOND.class.getSimpleName());
}
}
public static List<EnumBase> values() {
return List.of(FIRST, SECOND);
}
}
class MyEnumDriver {
public static void main(String[] args) {
// FIRST 1
System.out.println(MyEnum.FIRST.name() + " " + MyEnum.FIRST.ordinal());
// true
System.out.println(MyEnum.FIRST == MyEnum.FIRST);
// FIRST 2
System.out.println(MyEnum.SECOND.name() + " " + MyEnum.SECOND.ordinal());
// values
System.out.println(MyEnum.values());
}
}
Top comments (0)