October 30, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

In Anticipation of Tiger

  • May 29, 2003
  • By Apu Shah
  • Send Email »
  • More Articles »

Theme 5: Ease of Development

The Java language and syntax are being enhanced to make code more readable, expressive, comact, safer, and easier to develop, without sacrificing compatibility. These new language features are being incorporated after several years of discussion and comparison of Java to other programming languages. These features are the most anticipated amongst the Tiger release contents and have spawned numerous threads of discussion within the developer community. The changes will come in the form of class file format changes, generic (a.k.a. parameterized types like C++ templates) support, a 'foreach' type of looping construct, automatic conversion between primitive, and corresponding object data types, type-safe enums, an improved syntax for using static constants, and the use of metadata tags which allow the developer to insert simple declarative tags in the source code for which the compiler generates the necessary boilerplate code.

These changes will have an impact on the way developers write Java programs. Taking advantage of these changes will require the developer to learn new language features, new syntax, and must become part of the developer's arsenal. Let's look deeper into each of these new features.

  • Class File Format Changes

    These changes will modify and extend the Java Class File format to support updates to the Java platform and language specifications. The changes will add support for quicker and more efficient byte code verification, class literal support directly from the class file format, and will increase certain implicit size limits within the class file. These changes will be transparent to the application developer. No code changes would be required for existing codebases.

  • Support for Generics

    Generic support is the ability to specify a particular type of object used in a collection, rather than default to using the Object type for generic behaviour. These notions of genericity are based on parametric polymorphism. These concepts are best explained with an example illustrating the benefits and syntax changes.

    Let's say you have a method that prints all the Strings in the collection passed to it in lower case.
      /**
       * Print all the Strings in the Collection in lower case.
       **/
      public void printLowerCase(Collection c) {
        Iterator iter = c.iterator();
        while(iter.hasNext()) {
          String str = (String)iter.next();
          System.out.println(str.toLowerCase());
        }
      }
    

    The things to notice here are that an explicit cast to String is required when iterating through the Collection. This is error prone. If a programmer inadvertently passes a collection of any other type, this method would compile fine, only to blow up at runtime with a ClassCastException. The precondition for this code to correctly execute is that the Collection must contain Strings. This fact is not explicit from the method signature, but rather is expressed in the documentation for the method.

    Generics provide the way to avoid casting by binding generic collections to specifc types at compile time rather than runtime. The same method above written using generics would be:

      /**
       * Print all the Collection Strings in lower case.
       **/
      public void printLowerCase(Collection<String> c) {
        Iterator<String> iter = c.iterator();
        while(iter.hasNext()) {
          String str = iter.next();
          System.out.println(str.toLowerCase());
        }
      }
    

    Here, we explicity specify what type of Objects the Collection will contain, thereby eliminating the need for casting. The programmer's intent is now absolutely clear and is part of the method signature rather than the documentation. If a programmer inadvertently passes a collection of any other type, this method would not even compile. This eliminates runtime ClassCastExceptions altogether and provides compile-time type safety.

    Generics will improve code readability, expressiveness, and provide safety against runtime exceptions.

  • The 'foreach' type of construct: Tiger plans to introduce an additional for loop syntax with similar capability as the 'foreach' looping construct found in so many other languages. This addition is mainly to increase developer productivity and reduce the amount of code required to iterate through loops.

    Let's say you have to loop through a Collection of Strings. Currently, you may achieve the loop by using a while statement or a for statement, as illustrated below:

    Collection c;
    Iterator i = collection.iterator();
    while(i.hasNext()) {
      // Process element
    }
    
    for(Iterator i = c.iterator; i.hasNext() ; ) {
      // Process element.
    }
    

    Both these constructs require the creation of an Iterator object and explicit specification on how to iterate through the collection, by using the hasNext() method.

    The 'enhanced for' construct makes the code look like:

    Collection c;
    for( Object o : c ) {
      //Process element
    }
    

    This reads as 'for each Object o in Collection c'. Combined with generics support, this could be:

    Collection c;
    for( String o : c) {
      //Process element
    }
    

    The 'foreach' type construct eliminates the need for Iterator creation and delegates all details of how to iterate through the collection to the compiler. It also reduces the amount of code required to iterate through collections.

  • Automatic conversion between primitive types and corresponding object types: Java has a 'split type' system, which means there is a difference in the way primitive types and object types are handled. This forces the programmer to perform manual conversions between primitive types and corresponding object types in code.

    If you would like to add a primitive int to an Integer object, you would have to do:

    int i;
    Integer j;
    
    int k = i + j.intValue();
    Integer kObj = new Integer(k);
    

    In Tiger, the conversion between primitive types and their corresponding Object type will be automatic. This feature is also referred to as 'autoboxing of primitives'.

    The code is now as easy as:

    int i;
    Integer j;
    
    int k = i + j;
    Integer kObj = i + j;
    

    This feature almost removes all distinction between primitive types and corresponding object types for the programmer. It further allows the addition of primitive types to Collections, so this

    Collection c;
    int i;
    
    c.add(new Integer(i));
    

    becomes

    c.add(i);
  • Typesafe enums: An enum is a bounded set of distinct values that a particular object can take. They are similar to a grouping of constants representing all permissible values for a particular object. Tiger intends to add language-level support for the typesafe enum pattern. This pattern is best described by an example:

    /**
     * A type safe enum repesenting the states of a traffic
     * light
     **/
    public class TrafficSignal {
      /* 
        Clients should not be able to instantiate. This
        object can only take on a fixed set of values.
      */
      private TrafficSignal() { }
    
      String color;
    
      private static final TrafficSignal GREEN =
      new TrafficSignal("GREEN");
      private static final TrafficSignal YELLOW =
      new TrafficSignal("YELLOW");
      private static final TrafficSignal RED =
      new TrafficSignal("RED");
    
      public boolean equals(Object o) {
        if(o.getClass() != getClass())
          return(false);
        TrafficSignal signal = (TrafficSignal)o;
        return(signal.color == color);
      }
    }
    

    and use it as:

    TrafficSignal signal;
    if(signal.equals(TrafficSignal.GREEN))
    

    In Tiger, language-level support for this pattern will be provided, thereby reducing the code to look like:

    public enum TrafficSignal {
      GREEN("GREEN"), YELLOW("YELLOW"), RED("RED");
      
      private String color;
    
      TrafficSignal(String color) { this.color = color }
    }
    

    and use it as:

    TrafficSignal signal;
    if(signal == TrafficSignal.GREEN))
    

    You could even use these enums in switch statements, like this:

    TrafficSignal signal;
    switch(signal) {
      case TrafficSignal.RED: stop();
      case TrafficSignal.YELLOW: slowDown();
      case TrafficSignal.GREEN: go();
      default: slowDown();
    }
    

    Because the typesafe enum type is just like a class, we could add methods and fields and even use them in collections.

  • Improved syntax for using static constants: To use constants in Java, the programmer must either fully qualify the constant reference or implement an interface defining the constants. Consider an example of what is described as the 'Constants Antipattern':

    public interface Constants {
      public static final int DAYS_IN_WEEK = 7;
      public static final int DAYS_IN_YEAR = 365;
    }
    

    To use these constants, the programmer must either fully qualify the constant reference:

    int weeks_in_year =
        Constants.DAYS_IN_YEAR/Constants.DAYS_OF_WEEK;
    

    or implement the interface:

    public class Year implements Constants {
      int weeks_in_year = DAYS_IN_YEAR/DAYS_IN_WEEK;
    }
    

    Tiger intends to introduce a 'static import' facility that allows for referencing of static constants without implementing the interface or prefixing the class name of the defining class.

    import static Constants;
    
    public class Year {
      int weeks_in_year = DAYS_IN_YEAR/DAYS_IN_WEEK;
    }
    

    The import statement will make all static members of the Constants class available to the Year class. This compact syntax provides the benefits of not having to fully qualify the constant reference and overcomes the disadvantages of implementing an interface.

  • Metadata facility to annotate source code: Programmers writing EJBs and RMI-based apps need to define a lot of boilerplate code to implement their objects. For example, to implement a Remote object (in the RMI sense), a programmer must define the interface.

    package service;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface ServiceRunner extends Remote {
        Object executeService(Service s) throws RemoteException;
    }
    

    and define the implementation of the remote interface:

    package servicerunner;
    
    import java.rmi.*;
    import java.rmi.server.*;
    
    public class ServiceRunnerImpl extends UnicastRemoteObject
                                   implements ServiceRunner
    {
        public Object executeService(Service t) {
            ...
        }
    }
    

    Using Tiger's metadata facility would allow the programmer to write code using tags that instruct the compiler to generate the necessary boilerplate code for the remote interface:

    public class ServiceRunner { 
        @Remote public Object executeService(Service t) {
            ...
        }
    }
    

    This also annotates the source code by marking it to have certain characteristics.

    There is still much discussion about this feature, its implementation, extent, and scope. More details on this will be available as we come closer to the release date.

Summary

As you can see, this release is going to be a big one, especially with respect to language changes. Overall, with the introduction of these changes and additional APIs will come with some amount of learning curve but will make Java more developer friendly and easier to work with. The language changes widen Java's reach to cross-language developers. The performance enhancements will make this Java the fastest one ever. The focus on XML and Web Services makes Java a language of choice for modern network programming paradigms. This release will strengthen the mind-share and further increase the popularity of the platform.

Resources

About the Author

Apu Shah, a Java developer and avid follower of breaking Java trends since 1995, also writes a biweekly column on the events of the JCP on developer.com. If you have any thoughts on these features or would you like to see other features in Tiger, feel free to contact him at apu@jcpwatch.org.

# # #





Page 2 of 2



Comment and Contribute

 


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

 

 


Sitemap | Contact Us

Rocket Fuel