Using Enums

FRIDGE

The code in this book was compiled and executed using the JDK 5.0 alpha and beta releases, and it is possible that there are changes between these and the final release. If you want to switch between different compilers, you can use the - source 1.5 switch to the javac command.


Enums are new with Java 5.0. Enum is short for enumeration, and enums are useful when you want to define values that are meaningful to the user (in this case, other programmers) that can be switched against. The Enum is defined in the java.lang package.

When to Use an Enum

Programmers may be familiar with the enum, which programmers may be familiar with from C, C++, C#, or Pascal. A simple enum looks like this:

public enum Season { winter, spring, summer, fall }

An enum is an object that defines a list of acceptable values from which the caller can choose. It defines zero or more members, which are the named constants of the enum type. No two enum members can have the same name.

Java programmers have heretofore had to roll their own poor-man's enums by using constant- style names with int values, like this:

public interface Season {
   static winter = 0;
   static spring = 1; //etc..
}

Every field declaration in the body of an interface is implicitly public, static, and final. So the interface is used sometimes for constatnt declarations. If you want to make those constants available to your class, you implement the Season interface.

There are problems with having to do so, however. The first is that you need to write a lot of code to handle the situation, and rolling your own usually means that you are using an interface, as we do here, for something that it isn't intended for. This can cause clutter and confusion in your program.

Note that you can declare a public enum within a public class source file (remember that you can't declare more than one public class in the same source file).

You can also declare a public enum in its own .java file and compile it. Here is the enum replacement for our earlier interface:

Season.java
public enum Season { winter, spring, summer, fall }

That's all we have to do. The values for each of the seasons will be automatically assigned a numeric value, starting with 0, and incrementing one for each remaining enum value.

Let's look at the easiest way to implement the new enum construct.

EnumDemo.java
package net.javagarage.enums;

/*
We can loop over the values we put into the enum
using the values() method.
Note that the enum Seasons is compiled into a
separate unit, called EnumDemo$Seasons.class
*/
public class EnumDemo {

      /*declare the enum and add values to it. note that, like in C#, we don't use a ; to
 end this statement and we use commas to separate the values */

      private enum Seasons { winter, spring,
       summer, fall }

      //list the values
      public static void main(String[] args) {
            for (Seasons s : Seasons.values()){
                  System.out.println(s);
            }
      }

}

Running the preceding code outputs the following, as you would expect:

winter
spring
summer
fall

Switching Against Enums

The following code demonstrates how to switch against the values in an enum, which is what enums are commonly used to do:

package net.javagarage.enums;
/*
File: EnumSwitch.java
Purpose: show how to switch against the values in an enum.
*/

public class EnumSwitch {

      private enum Color { red, blue, green }

      //list the values
      public static void main(String[] args) {
            //refer to the qualified value
            doIt(Color.red);

      }

      /*note that you switch against the UNQUALIFIED name. that is, "case Color.red:" is a
 compiler error */

      private static void doIt(Color c){

      switch (c) {
      case red: 
            System.out.println("value is " + Color.red);
            break;
      case green: 
            System.out.println("value is " + Color.green);
            break;
      case blue: 
            System.out.println("value is : " + Color.blue);
            break;
      default : 
            System.out.println("default");
      }
      }

}

Adding Fields and Methods to Enums

You can add fields and methods to enums, just like you would a regular class. The following shows that you can use an enum much like you would a class. You can define static or non-static fields and methods, and define constructors. You can define different levels of visibility, as with a class.

EnumDemo.java
package net.javagarage.enums;

/*
File: EnumDemo.java
Purpose: show how to use an enum that also defines its own fields and methods
*/

public class EnumWithMethods {

//declare the enum and add values to it.

public enum Season {

      winter, spring, summer, fall;

      private final static String location = "Phoenix";

      public static Season getBest(){
            if (location.equals("Phoenix"))
                  return winter;
            else
                  return summer;

      }

      public static void main(String[] args) {

      System.out.println(Season.getBest());
      }
}

Notice one limitation of enums that is not often present in other features of the Java language, placement of the values list is limited to immediately following the enum declaration. That is, you'd see a compilation error if you switched the following two lines of code in the preceding example:

private final static String location = "Phoenix"; //wrong!
winter, spring, summer, fall;

The enum of seasons comes following the field here, which is illegal. The compiler would let you know an identifier is expected.

Enum Constructors

You can create an enum with a constructor as well, just like you would in a regular class. The following code shows how.

package net.javagarage.enums;

public class EnumConstructor {

      public static void main(String[] a) {

            //call our enum using the values method
            for (Temp t : Temp.values())
                  System.out.println(t + " is : " + t.getValue());
      }

      //make the enum
      public enum Temp {
            absoluteZero(-459), freezing(32),
            boiling(212), paperBurns(451);

      //constructor here
      Temp(int value) {
            this.value = value;
      }

      //regular field—but make it final,
      //since that is the point, to make constants
      private final int value;

      //regular get method
      public int getValue() {
      return value;
      }

      }
}

The output is the following:

absoluteZero is : -459
freezing is : 32
boiling is : 212
paperBurns is : 451

Now. Just because enums share the capability to define methods and fields and constructors like regular classes does not mean that defining and using all of those gadgets is a good idea. If you want that kind of functionality, you probably should write a class. Enums are very useful as a shortcut for initializing int variables in a list of constants when the values are meaningful only within the context of the other values. They're perfect for that. They're popular in many programming languages. But if you need a class, make a class, man, not an enum.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.246.193