Difference between revisions of "Enums"
From Suhrid.net Wiki
Jump to navigationJump to search(30 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | == Introduction == | ||
+ | |||
* Enums are a feature that allows a variable to be restricted to having only a few predefined values. | * Enums are a feature that allows a variable to be restricted to having only a few predefined values. | ||
+ | * Type-safe in built alternative as opposed to representing constants with integers or creating enum patterns. | ||
* e.g. if we want to restrict a variable that represents t-shirt sizes and colors to only one of four possible sizes, we can use an enum: | * e.g. if we want to restrict a variable that represents t-shirt sizes and colors to only one of four possible sizes, we can use an enum: | ||
Line 37: | Line 40: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | * Enum instances are instances of the enum type. Like instances of any class. | ||
+ | |||
+ | == Declaration == | ||
+ | |||
+ | * Enums are sort of like regular java classes - they can have constructors, variables and methods. | ||
+ | * But with restrictions... | ||
+ | |||
+ | === Enum Types === | ||
+ | |||
+ | * They cannot be declared final. Otherwise we cannot have constant specific class bodies, also they cannot be abstract. | ||
+ | * They can be defined in their own files - like public classes and can be run as a standalone application. | ||
+ | * Example : | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | public enum State { | ||
+ | IDLE, BUSY, WAITING; | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | System.out.println(IDLE); //No need to qualify with the enum type name | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | * They can be defined within an enclosing class. If yes, then they become implicitly static - and are accessible like static inner classes. | ||
+ | * '''Cannot''' be declared within methods. (Similar to static inner classes cannot) | ||
+ | |||
+ | ==== Enum Extensibility ==== | ||
+ | * An enum can also implement interfaces. (But not extend classes) | ||
+ | * Example on how we can create a Runnable enum and use it in a thread. | ||
+ | * Enums themselves '''cannot''' be extended. | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | enum ThreadEnum implements Runnable { | ||
+ | |||
+ | ONE, TWO, THREE; | ||
+ | |||
+ | public void run() { | ||
+ | System.out.println("Woo"); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | public class Test { | ||
+ | void go() { | ||
+ | Thread t = new Thread(ThreadEnum.ONE); | ||
+ | t.start(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Enums can be defined within other classes '''or within other enums.''' When it is nested, the enum type becomes implicitly static. | ||
+ | * Because of their static nature, Enums can't be defined within regular inner classes or method local inner classes. | ||
+ | * They can be defined within top level classes or within static inner classes. | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | public class Info { | ||
+ | |||
+ | enum Cities {Delhi, Dakar, Denver}; | ||
+ | |||
+ | public static enum Directions {LEFT, RIGHT}; | ||
+ | |||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Enum Constants === | ||
+ | |||
+ | * The constants '''''must be specified''''' in the beginning, before anything else. | ||
+ | * The enum constants '''must be qualified with the enumtype name''' when used outside the enum. | ||
+ | * An enum constant has to be qualified with its enum type name ! Except when: | ||
+ | * The '''type name can be skipped only for methods defined within the enum'''. | ||
+ | * The type name must also be skipped when using enums in case constants. (The enum type has to be imported unless it is accessible) | ||
+ | * The enum constant can be imported with a static import. | ||
+ | * Enum constants are by default '''final and static.''' | ||
+ | * NO modifier is allowed for the enum constant. | ||
+ | |||
+ | === Enum Constructors === | ||
+ | * Enum constructors are implicitly '''private.'''. This is to prevent instances of enums being created. | ||
+ | * For e.g. if we want to specify inches for the T-Shirt Size | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | enum TShirtSize { | ||
+ | |||
+ | S(38), | ||
+ | M(40), | ||
+ | L, //Uses the default constructor | ||
+ | XL(44); | ||
+ | |||
+ | private int inches; | ||
+ | |||
+ | TShirtSize() { | ||
+ | |||
+ | } | ||
+ | |||
+ | TShirtSize(int inches) { | ||
+ | this.inches = inches; | ||
+ | } | ||
+ | |||
+ | public int getInches() { | ||
+ | return inches; | ||
+ | } | ||
+ | |||
+ | }; | ||
+ | |||
+ | class TShirt { | ||
+ | void foo() { | ||
+ | TShirtSize size = TShirtSize.M; | ||
+ | System.out.println(size.getInches()); //Prints 40; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Enum methods === | ||
+ | |||
+ | * Can have any access modifier. | ||
+ | * Can be abstract. If abstract method is declared, all enum constants have to override it in constant specific class body. | ||
+ | * Can be final as well. Cannot be overriden in constant specific class body. | ||
+ | |||
+ | === Constant specific class body === | ||
+ | |||
+ | * Works like anonymous inner classes. | ||
+ | * Situation where we need to oveerride the regular behaviour of an enum, for a specific constant. | ||
+ | * Example: | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | enum TShirtSize { | ||
+ | |||
+ | S(38), | ||
+ | M(40), | ||
+ | L(42) { | ||
+ | public int getInches() { | ||
+ | if(Locale.getDefault().equals(Locale.US)) { | ||
+ | return 44; | ||
+ | } else { | ||
+ | return 42; | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | XL(44); | ||
+ | |||
+ | private int inches; | ||
+ | |||
+ | TShirtSize() { | ||
+ | |||
+ | } | ||
+ | |||
+ | TShirtSize(int inches) { | ||
+ | this.inches = inches; | ||
+ | } | ||
+ | |||
+ | public int getInches() { | ||
+ | return inches; | ||
+ | } | ||
+ | |||
+ | }; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Think of a constant specific class body as an anonymous inner class which extends the class in which it is defined. | ||
+ | * Since it extends the enum class, the constant specific class body '''does not have access to private instance variables (since they are not inherited).''' | ||
+ | * However like an inner class, '''it can access instance variables which are not private, and private static variables.''' | ||
+ | |||
+ | == Inherited/Implicit behavior == | ||
+ | |||
+ | * Any enum we declare will inherit from the java.lang.Enum class which provides the default enum behavior. | ||
+ | * Several methods are defined as final in java.lang.Enum such as equals() and hashCode(). | ||
+ | * The equals() implementation is just a reference check since enum instances cannot be created by the end user. | ||
+ | * Thus, for any enum enum1.equals(enum2) is equivalent to enum1 == enum2. | ||
+ | * Enums inherit a name() method - to print the name. | ||
+ | * They also have an oridinal() method - which returns an int position (starting from 0) indicating the order in which they were declared. | ||
+ | * Enums are also comparable and serializable, they have a compareTo() method - which internal uses the ordinal to compare. | ||
+ | |||
+ | * The enum class also has couple of static methods which are implicitly provided for all enums (like the length attribute for any array). They are: | ||
+ | * values() : returns all the Enum constants in the order in which they have been defined. | ||
+ | * valueOf(String name) : reutrns the Enum constant with the specified name. | ||
+ | |||
+ | |||
+ | |||
+ | [[Category:OCPJP]] |
Latest revision as of 23:08, 3 September 2011
Contents
Introduction
- Enums are a feature that allows a variable to be restricted to having only a few predefined values.
- Type-safe in built alternative as opposed to representing constants with integers or creating enum patterns.
- e.g. if we want to restrict a variable that represents t-shirt sizes and colors to only one of four possible sizes, we can use an enum:
enum TShirtSize {
S,M, L, XL
};
enum TShirtColor {
RED, BLACK, BLUE, WHITE;
}
public class TShirt {
private TShirtSize size;
private TShirtColor color;
public TShirt(TShirtSize size, TShirtColor color) {
this.size = size;
this.color = color;
}
public String toString() {
return size + "," + color;
}
public static void main(String[] args) {
TShirt t1 = new TShirt(TShirtSize.M, TShirtColor.RED);
System.out.println(t1); //Will print: M, RED;
TShirt t2 = new TShirt(TShirtSize.L, TShirtColor.WHITE);
System.out.println(t2); //Will print: L, WHITE;
}
}
- Enum instances are instances of the enum type. Like instances of any class.
Declaration
- Enums are sort of like regular java classes - they can have constructors, variables and methods.
- But with restrictions...
Enum Types
- They cannot be declared final. Otherwise we cannot have constant specific class bodies, also they cannot be abstract.
- They can be defined in their own files - like public classes and can be run as a standalone application.
- Example :
public enum State {
IDLE, BUSY, WAITING;
public static void main(String[] args) {
System.out.println(IDLE); //No need to qualify with the enum type name
}
}
- They can be defined within an enclosing class. If yes, then they become implicitly static - and are accessible like static inner classes.
- Cannot be declared within methods. (Similar to static inner classes cannot)
Enum Extensibility
- An enum can also implement interfaces. (But not extend classes)
- Example on how we can create a Runnable enum and use it in a thread.
- Enums themselves cannot be extended.
enum ThreadEnum implements Runnable {
ONE, TWO, THREE;
public void run() {
System.out.println("Woo");
}
}
public class Test {
void go() {
Thread t = new Thread(ThreadEnum.ONE);
t.start();
}
}
- Enums can be defined within other classes or within other enums. When it is nested, the enum type becomes implicitly static.
- Because of their static nature, Enums can't be defined within regular inner classes or method local inner classes.
- They can be defined within top level classes or within static inner classes.
public class Info {
enum Cities {Delhi, Dakar, Denver};
public static enum Directions {LEFT, RIGHT};
}
Enum Constants
- The constants must be specified in the beginning, before anything else.
- The enum constants must be qualified with the enumtype name when used outside the enum.
- An enum constant has to be qualified with its enum type name ! Except when:
- The type name can be skipped only for methods defined within the enum.
- The type name must also be skipped when using enums in case constants. (The enum type has to be imported unless it is accessible)
- The enum constant can be imported with a static import.
- Enum constants are by default final and static.
- NO modifier is allowed for the enum constant.
Enum Constructors
- Enum constructors are implicitly private.. This is to prevent instances of enums being created.
- For e.g. if we want to specify inches for the T-Shirt Size
enum TShirtSize {
S(38),
M(40),
L, //Uses the default constructor
XL(44);
private int inches;
TShirtSize() {
}
TShirtSize(int inches) {
this.inches = inches;
}
public int getInches() {
return inches;
}
};
class TShirt {
void foo() {
TShirtSize size = TShirtSize.M;
System.out.println(size.getInches()); //Prints 40;
}
}
Enum methods
- Can have any access modifier.
- Can be abstract. If abstract method is declared, all enum constants have to override it in constant specific class body.
- Can be final as well. Cannot be overriden in constant specific class body.
Constant specific class body
- Works like anonymous inner classes.
- Situation where we need to oveerride the regular behaviour of an enum, for a specific constant.
- Example:
enum TShirtSize {
S(38),
M(40),
L(42) {
public int getInches() {
if(Locale.getDefault().equals(Locale.US)) {
return 44;
} else {
return 42;
}
}
},
XL(44);
private int inches;
TShirtSize() {
}
TShirtSize(int inches) {
this.inches = inches;
}
public int getInches() {
return inches;
}
};
- Think of a constant specific class body as an anonymous inner class which extends the class in which it is defined.
- Since it extends the enum class, the constant specific class body does not have access to private instance variables (since they are not inherited).
- However like an inner class, it can access instance variables which are not private, and private static variables.
Inherited/Implicit behavior
- Any enum we declare will inherit from the java.lang.Enum class which provides the default enum behavior.
- Several methods are defined as final in java.lang.Enum such as equals() and hashCode().
- The equals() implementation is just a reference check since enum instances cannot be created by the end user.
- Thus, for any enum enum1.equals(enum2) is equivalent to enum1 == enum2.
- Enums inherit a name() method - to print the name.
- They also have an oridinal() method - which returns an int position (starting from 0) indicating the order in which they were declared.
- Enums are also comparable and serializable, they have a compareTo() method - which internal uses the ordinal to compare.
- The enum class also has couple of static methods which are implicitly provided for all enums (like the length attribute for any array). They are:
- values() : returns all the Enum constants in the order in which they have been defined.
- valueOf(String name) : reutrns the Enum constant with the specified name.