Guide for understanding enum in java
What is enum in java
Enumerations (in general) are generally a set of related constants. They have been in other programming languages like C++ from beginning. After JDK 1.4, java designers decided to support it in java also, and it was officially released in JDK 1.5 release.Enumeration in java is supported by keyword enum. enums are a special type of class that always extends java.lang.Enum.
A simple usage will look like this:
public enum DIRECTION {
EAST,
WEST,
NORTH,
SOUTH //optionally can end with ";"
}Here EAST, WEST, NORTH and SOUTH are final static inner classes of Direction of type Direction extends java.lang.Enum.
How enum is related to java.lang.Enum
As mentioned earlier, enums extends java.lang.Enum. java.lang.Enum is an abstract class. This is the common base class of all Java language enumeration types.It is declared as follows:
public abstract class Enum>
extends Object
implements Comparable, Serializable
This clearly means that enums are comparable and serializable implicitly. Also, all enum types in java are singleton by default. So, you can compare enum types using ‘==’ operator also.
This also means that all enums extends java.lang.Enum, so they can not extend any other class because java does not support multiple inheritance this way. But, enums can implement any number of interfaces.
A very basic enum declaration
enum can be declared using following syntax.access-modifier enum enum-name
{
enum_type_1,
enum_type_2 //(optioanl semi colon)
}Lets see some examples:
enum Direction {
EAST,
WEST,
NORTH,
SOUTH
}
public enum Direction {
EAST,
WEST,
NORTH,
SOUTH;
}
enum declaration inside a class
When declared inside a class, enums are always static by default and can be accessed as OutClassRef.EnumType.EnumVar.public class TestOuter
{
enum Direction
{
EAST,
WEST,
NORTH,
SOUTH
}
}Like for above enum, if declared inside TestOuter.java, we can access a direction using TestOuter.Direction.NORTH.
How enum constructors can be used
By default, enums do not require you to give constructor definitions and their default values is always represented by string used in declaration.Though, you can give define your own constructors to initialize the state of enum types.
enum Direction {
// Enum types
EAST(0), WEST(180), NORTH(90), SOUTH(270);
// Constructor
private Direction(final int angle) {
this.angle = angle;
}
// Internal state
private int angle;
public int getAngle() {
return angle;
}
}
Can we extend enum types?
NO, you can not. Enum types are final by default and hence can not be extended. Yet, you are free to implement any number of interfaces as you like.How to use template methods in enum
Remember that the enum is basically a special class type, and can have methods and fields just like any other class. So, you can define a template for enum creation also. For example: If we want that each enum type of Direction should be able to shout the direction name, when needed. This can be done by defining a abstract method inside Direction, which each enum has to override.package enumTest;
public enum Direction {
// Enum types
EAST(0) {
@Override
public void shout() {
System.out.println("Direction is East !!!");
}
},
WEST(180) {
@Override
public void shout() {
System.out.println("Direction is West !!!");
}
},
NORTH(90) {
@Override
public void shout() {
System.out.println("Direction is North !!!");
}
},
SOUTH(270) {
@Override
public void shout() {
System.out.println("Direction is South !!!");
}
};
// Constructor
private Direction(final int angle) {
this.angle = angle;
}
// Internal state
private int angle;
public int getAngle() {
return angle;
}
// Abstract method which need to be implemented
public abstract void shout();
}
How to do reverse lookup in enums
Often in your object model it is common to have data that is naturally “associated” with an enumeration. So, it is desirable to “lookup” the associated enumeration using the argument value. This is easy to do using a static java.util.Map.This map will be used to store the mapping between an enumeration type and its associated value.
Lets modify our Direction enum to support reverse lookup, such that it somebody knows the exact angle, he can get the reference to related enum type.
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
enum Direction {
// Enum types
EAST(0), WEST(180), NORTH(90), SOUTH(270);
// Constructor
private Direction(final int angle) {
this.angle = angle;
}
// Internal state
private int angle;
public int getAngle() {
return angle;
}
// Lookup table
private static final Map lookup = new HashMap();
// Populate the lookup table on loading time
static {
for (Direction s : EnumSet.allOf(Direction.class))
lookup.put(s.getAngle(), s);
}
// This method can be used for reverse lookup purpose
public static Direction get(int angle) {
return lookup.get(angle);
}
}
public class Test {
public static void main(String[] args) {
// Angle lookup
System.out.println(Direction.NORTH.getAngle());
// Reverse lookup by angle
System.out.println(Direction.get(90));
}
}
Different enum collections
Two classes have been added to java.util in support of enums: EnumSet (a high-performance Set implementation for enums; all members of an enum set must be of the same enum type) and EnumMap (a high-performance Map implementation for use with enum keys).java.util.EnumSet
This class is defined as follows:
public abstract class EnumSet>
extends AbstractSet
implements Cloneable, Serializable
A specialized Set implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.
public class Test {
public static void main(String[] args) {
Set enumSet = EnumSet.of( Direction.EAST,
Direction.WEST,
Direction.NORTH,
Direction.SOUTH
);
}
}Like most collection implementations EnumSet is not synchronized. If multiple threads access an enum set concurrently, and at least one of the threads modifies the set, it should be synchronized externally.
Null elements are not permitted. Also, these sets guarantee the ordering of the elements in the set based on their order in the enumeration constants are declared. Performance and memory benefits are very high in compare to a regular set implementation.
java.util.EnumMap
This is declared as:
public class EnumMap,V>
extends AbstractMap
implements Serializable, Cloneable
A specialized Map implementation for use with enum type keys. Also, all of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created.
Like EnumSet, Null keys are not permitted and is not synchronized as well.
public class Test {
public static void main(String[] args)
{
//Keys can be only of type Direction
Map enumMap = new EnumMap(Direction.class);
//Populate the Map
enumMap.put(Direction.EAST, Direction.EAST.getAngle());
enumMap.put(Direction.WEST, Direction.WEST.getAngle());
enumMap.put(Direction.NORTH, Direction.NORTH.getAngle());
enumMap.put(Direction.SOUTH, Direction.SOUTH.getAngle());
}
}
Collecting key notes about enum
- enums are implicitly final subclasses of java.lang.Enum
- if an enum is a member of a class, it’s implicitly static
- new can never be used with an enum, even within the enum type itself
- name and valueOf simply use the text of the enum constants, while toString may be overridden to provide any content, if desired
- for enum constants, equals and == amount to the same thing, and can be used interchangeably
- enum constants are implicitly public static final
- the order of appearance of enum constants is called their “natural order”, and defines the order used by other items as well : compareTo, iteration order of values , EnumSet, EnumSet.range.
- Constructors for an enum type should be declared as private. The compiler allows non private declares for constructors, but this seems misleading to the reader, since new can never be used with enum types.
- Since these enumeration instances are all effectively singletons, they can be compared for equality using identity (“==”).
- you can use Enum in Java inside Switch statement like int or char primitive data type
0 comments:
Post a Comment