November 21, 2014
Hot Topics:

J2SE 1.5 - Effective Java Programming with Tiger

  • November 21, 2003
  • By Arulazi Dhesiaseelan
  • Send Email »
  • More Articles »

Typesafe Enumerations

What is enum?

Enum is a special kind of class declaration. A typesafe enum facility defines a fixed set of constant legal values for types. This feature is borrowed from the C language and has been incorporated into the Java language in the Tiger release.

Advantages of enum

The proposed enum facility has more advantages when compared with the traditional int enum approach in Java. The advantages are outlined below.

  • enum provides compile time type safety
  • enum provides proper name spacing for its types
  • Performance comparable to int constants
  • Typesafe constants do not require a compilation when clients modify constants
  • Printed values are informative
  • enum can be used in collections because they are objects
  • enum is a special kind of class declaration; hence, one can add arbitrary fields and methods
  • enum can be made to implement arbitrary interfaces

Traditional enum pattern

Listing 5 shows the commonly used pattern for enumerated types in Java that suffer from many drawbacks. In this approach, whenever you modify the client code, you need to recompile.

public class Continent {
   public static final int CONTINENT_AFRICA          = 0;
   public static final int CONTINENT _ASIA           = 1;
   public static final int CONTINENT _EUROPE         = 2;
   public static final int CONTINENT_NORTH_AMERICA   = 3;
   public static final int CONTINENT_OCEANIA         = 4;
   public static final int CONTINENT_SOUTH_AMERICA   = 5;
}

Listing 5: enum pattern with fallbacks.

Typesafe enum pattern

Java provides an alternative method to overcome the drawbacks of the traditional approach. This is called the typesafe enum pattern. This pattern defines a class that represents a single element of an enumerated type that doesn't provide any public constructors to it. For each constant in the enumerated type, provide static final fields. Listing 6 shows this pattern approach. This pattern provides compile time type safety by allowing that only any of the six continents defined can be passed to a method which defines a parameter of type Continent.

public class Continent {
    private final String name;

    private Continent(String name) { this.name = name; }

    public String toString()  { return name; }

    public static final Continent AFRICA =
        new Continent ("africa ");
    public static final Continent ASIA =
        new Continent ("asia");
    public static final Continent EUROPE  =
        new Continent ("europe");
    public static final Continent NORTH_AMERICA =
        new Continent ("north america");
    public static final Continent OCEANIA =
        new Continent ("oceania");
    public static final Continent SOUTH_AMERICA =
        new Continent ("south america");
}

Listing 6: The typesafe enum pattern.

Proposed enum facility

The proposed facility is simple and readable. The construct can be used with switch statements. Listing 7 shows the usage of the proposed enum facility for the Java language.

public class EnumFacility {
    enum Continent { africa , asia, europe, north_america, oceania,
                     south_america };
  public static void main(String args[]) {
    System.out.println("Continents are : " + Continent.VALUES);
    for ( Continent c : Continent.VALUES ) {
      // switch on enum
      switch(c) {
        case Continent.africa:
        System.out.println("in africa.");
        break;
        case Continent.asia:
        System.out.println("in asia.");
        break;
        case Continent.europe:
        System.out.println("in europe.");
        break;
        case Continent.north_america:
        System.out.println("in north_america.");
        break;
        case Continent.oceania:
        System.out.println("in oceania.");
        break;
        case Continent.south_america:
        System.out.println("in south_america.");
        break;
      }
    }
  }
}

Listing 7: Proposed typesafe enum facility.

Autoboxing

What is autoboxing?

Developers are burdened when they convert primitive types to wrapper (reference) types (for example, converting int to Integer type). Adding primitive types to a collection is not possible unless they are converted to the corresponding reference type. To overcome this drawback of the current type system, the need for automatic conversion of primitive type data to their corresponding wrapper type data was proposed. This conversion mechanism is known as autoboxing.

Listing 8 illustrates the code that achieves autoboxing in a collection. In this code sample, the primitive type int is added to a collection that holds an Integer reference. The compiler takes care of the type conversion for you.

import java.util.*;

public class AutoBoxing {
  static List<Integer> testAutoBoxing(int ii) {
    int i = 0;
    List<Integer> arrayList = new ArrayList<Integer>();
    arrayList.add(++i);
    arrayList.add(new Integer(11));
    arrayList.add(++ii);
    return arrayList;
  }
  public static void main(String args[]) {
    List<Integer> arrayList = testAutoBoxing(110);
    for (Integer i : arrayList)
      System.out.println(i);
  }
}

Listing 8: Autoboxing in a Collection.

There are several other forms of conversion that are supported by the compiler. Refer to JSR201 for more information: http://jcp.org/aboutJava/communityprocess/jsr/tiger/autoboxing.html.

Enhanced for Statement

What is wrong with the current for statement?

The current for statement is very efficient and powerful in all aspects. But, it is not optimized when it iterates over a collection because the iterators are used only for getting elements out of a collection and serve no other purpose. Generics helped make this situation better by adding the type safety to the collection. This resulted in proposing "enhanced for" statements with generics additions to it. With this new feature, the compiler takes care of the iterator for you. Listing 9 details the usage of "enhanced for" statements.

import java.util.*;

public class TestForStatements {

  static StringBuffer buffer = null;
  public static void testCurrentForStatements(Collection c) {
    buffer = new StringBuffer();
    for (Iterator i = c.iterator(); i.hasNext(); ) {
      String s = (String) i.next();
      buffer.append(s+"\n");
    }
    System.out.println("Collection elements from traditional for
                        statement : \n" + buffer.toString());
  }
    public static void testEnhancedForStatements(Collection<String>
                                                 c) {
    buffer = new StringBuffer();
    for (String s : c) {
      buffer.append(s+"\n");
    }
    System.out.println("Collection elements from enhanced for
                        statement : \n" + buffer.toString());
  }
  public static void main(String args[]) {
    List featureList = new ArrayList();
    featureList.add("Java java = new Java();");
    featureList.add("java.addFeature(\"generics\");");
    featureList.add("java.addFeature(\"enum facility\");");
    featureList.add("java.addFeature(\"enhanced for\");");
    featureList.add("java.addFeature(\"auto boxing\");");
    featureList.add("java.addFeature(\"static import\");");
    featureList.add("Tiger.commitFeatureSet(java);");
    testCurrentForStatements(featureList);
    testEnhancedForStatements(featureList);
  }
}

Listing 9: "enhanced for" statements usage in a collection.

Using the "enhanced for" statement in an int array

The "enhanced for loop" has been specifically designed for iteration over collections and arrays. Its usage in an integer array is shown in Listing 10.

public class TestIntegerArrayUsingEnhancedForLoop {
  public static void main(String args[]) {
    int [] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int sum = 0;
    for (int e : a)
      sum += e;
    System.out.println("Array Sum : " + sum);
  }
}

Listing 10: "enhanced for" statements usage in an integer array.

Static Import

Rationale for static import

In the Java world, when using any mathematical functions from the "java.lang.Math" package or when using named constants, one has to prefix the method name or field name with the class name. This way of coding looks more verbose. To provide convenience to the developers, the concept of a static import was proposed. By using this, one can allow the import of static methods and fields similar to classes and interfaces.

import static java.lang.StrictMath.*; // import static
import static java.lang.System.*; // import static

public class StaticImport {
  static void testStaticImport() {
    out.println("The square root of PI is : " + sqrt(PI));
  }
  public static void main(String args[]) {
    testStaticImport();
  }
}

Listing 11: Usage of static import.

In Listing 11, the usage of static import is illustrated. The traditional approach is discussed below.

When accessing a static method, you need to prefix with the class name. For example,

  Math.sqrt(Math.PI);
  StrictMath.IEEEremainder(4.0, 2.0);
System.out.println("hello");

When accessing named constants, you need to prefix with the class name. For example,

  Math.PI

This approach makes code more verbose. The static import helps overcome this approach. This is a simple feature, but yet a convincing one for developers.

Conclusion

The features that were discussed in this article are only a subset of features that are planned to ship with Tiger. These features are developer savvy and yet powerful additions to the Java Programming language. Most of the listings in this article are tested with the Generics early access compiler version 2.2. Although enough features are targeted towards the Tiger release, the final specification will become soon available for review once the component JSRs releases them.

References

JSR 176-J2SETM 1.5 (Tiger) Release Contents
http://www.jcp.org/en/jsr/detail?id=176

JSR 14-Add Generic Types To The JavaTM Programming Language
http://www.jcp.org/en/jsr/detail?id=014

JSR 201-Extending the JavaTM Programming Language with Enumerations, Autoboxing, Enhanced for loops and Static Import
http://www.jcp.org/en/jsr/detail?id=201

Generics Prototype for JSR014
http://developer.java.sun.com/developer/earlyAccess/adding_generics/ (you must be a registered member of the Java Developer Connection)

GJ: A Generic Java Language Extension
http://www.research.avayalabs.com/user/wadler/gj/

About the Author

Arulazi Dhesiaseelan has been working as a Senior Software Engineer for the Hewlett-Packard Company, India. He has a Master of Computer Applications degree from PSG College of Technology, India. He has more than three years of industry experience. He was also involved in the UDDI4J project hosted at http://uddi4j.org. He has been working on Web Service related technologies such as WSDL, UDDI, and SOAP. Currently, he is involved in developing an object-based infrastructure for mobile solutions. He can be reached at aruld@acm.org.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel