Difference between revisions of "Enums"

From Suhrid.net Wiki
Jump to navigationJump to search
 
(6 intermediate revisions by the same user not shown)
Line 50: Line 50:
 
=== Enum Types ===
 
=== Enum Types ===
  
* Enum can be declared ONLY with public or default modifier.
 
 
* They cannot be declared final. Otherwise we cannot have constant specific class bodies, also they cannot be abstract.
 
* They cannot be declared final. Otherwise we cannot have constant specific class bodies, also they cannot be abstract.
* '''''The only modifier permitted for an enum is public.'''''
 
 
* They can be defined in their own files - like public classes and can be run as a standalone application.
 
* They can be defined in their own files - like public classes and can be run as a standalone application.
 
* Example :
 
* Example :
Line 71: Line 69:
 
* '''Cannot''' be declared within methods. (Similar to static inner classes cannot)
 
* '''Cannot''' be declared within methods. (Similar to static inner classes cannot)
  
 
+
==== Enum Extensibility ====
 
* An enum can also implement interfaces. (But not extend classes)
 
* 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.
 
* Example on how we can create a Runnable enum and use it in a thread.
 +
* Enums themselves '''cannot''' be extended.
  
 
<syntaxhighlight lang="java5">
 
<syntaxhighlight lang="java5">
Line 115: Line 114:
  
 
* The constants '''''must be specified''''' in the beginning, before anything else.
 
* 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.
+
* The enum constants '''must be qualified with the enumtype name''' when used outside the enum.
* The type name can be skipped only for methods defined within 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.'''
 
* Enum constants are by default '''final and static.'''
 
* NO modifier is allowed for the enum constant.
 
* NO modifier is allowed for the enum constant.

Latest revision as of 23:08, 3 September 2011

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.