Tuesday, September 21, 2010

Enums in java

In prior releases, the standard way to represent an enumerated type was the int Enum pattern:

// int Enum Pattern - has severe problems!
public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL   = 3;
But these are not type safe, and clearly naming them is bit of a problem. So in Java 5, they introduced Enums.

Eg.
enum Season { WINTER, SPRING, SUMMER, FALL } 
public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
        SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }

    public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } 
  
Note on Semicolon ( ; )
Enum embedded inside a class. Outside the enclosing class, elements are referenced as Outter.Color.RED, Outter.Color.BLUE, etc.
public class Outter {
 public enum Color {
   WHITE, BLACK, RED, YELLOW, BLUE
 }
}
Enum that overrides toString method. A semicolon after the last element is required to be able to compile it. More details on overriding enum toString method can be found.
public enum Color {
 WHITE, BLACK, RED, YELLOW, BLUE;  //; is required here.

 @Override public String toString() {
   //only capitalize the first letter
   String s = super.toString();
   return s.substring(0, 1) + s.substring(1).toLowerCase();
 }
}
Iterating enum through Value method...

for ( Color c :Color.values() ) {
         System.out.print( c + " " );
}


Enum constants may act as case labels in switch 
 enum Grade A, B, C, D, F, INCOMPLETE };
class Student {

  private String firstName;
  private String lastName;
  private Grade grade;

  public Student(String firstName, String lastName) ;

//getters and setters of grade
 public void assignGrade(Grade grade) {
    this.grade = grade;
  }

  public Grade getGrade() {
    return grade;
  }
 

Now we can have switch block as :
switch (student1.getGrade()) {
      case A: 
        outputText.append(" excelled with a grade of A");
        break;   
      case B: // fall through to C
      case C: 
        outputText.append(" passed with a grade of ")
                  .append(student1.getGrade().toString());
        break;
      case D: // fall through to F
      case F:
        outputText.append(" failed with a grade of ")
                  .append(student1.getGrade().toString());
        break;
      case INCOMPLETE:
        outputText.append(" did not complete the class.");
        break;
      default:
        outputText.append(" has a grade of ")
                  .append(student1.getGrade().toString());
        break;
    }



Enum with additional fields and custom constructor. Enum constructors must be either private or package default, and protected or public access modifier is not allowed. When custom constructor is declared, all elements declaration must match that constructor.
public enum Color { //Color is of type enum
 WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);

 private int code;

 private Color(int c) {
   code = c;
 }

 public int getCode() {
   return code;
 }
Enum that implements interfaces. Enum can implement any interfaces. All enum types implicitly implements java.io.Serializable, and java.lang.Comparable.
public enum Color implements Runnable {
 WHITE, BLACK, RED, YELLOW, BLUE;

 public void run() {
   System.out.println("name()=" + name() +
       ", toString()=" + toString());
 }
}
A sample test program to invoke this run() method:
for(Color c : Color.values()) {
 c.run();
}
Or,
for(Runnable r : Color.values()) {
 r.run();
}
Enum and their super-class
All java enum E implicitly extends java.lang.Enum. Since java doesn't allow multiple inheritance, enum types can't have superclass. They can't even extend from java.lang.Enum, nor java.lang.Object. It also means enum A can't inherit or extend enum B.

For example, the following is an invalid enum declaration:
public enum MyType extends Object {
ONE, TWO
}
Compiler error:
MyType.java:3: '{' expected
public enum MyType extends Object {
MyType.java:6:  expected
2 errors
 
The correct form should be:
public enum MyType {
ONE, TWO
}

Custom string values for enums
The default string value for java enum is its face value, or the element name. However, you can customize the string value by overriding toString() method. For example,
public enum MyType {
ONE {
    public String toString() {
        return "this is one";
    }
},

TWO {
    public String toString() {
        return "this is two";
    }
}
}
Running the following test code will produce this:
public class EnumTest {
public static void main(String[] args) {
    System.out.println(MyType.ONE);
    System.out.println(MyType.TWO);
}
}
-------------
this is one
this is two
Another interesting fact is, once you override toString() method, you in effect turn each element into an anonymous inner class. So after compiling the above enum class, you will see a long list of class files:
MyType.class
MyType$1.class
MyType$2.class

0 comments:

Post a Comment