Journal Articles

CVu Journal Vol 17, #5 - Oct 2005 + Programming Topics
Browse in : All > Journals > CVu > 175 (15)
All > Topics > Programming (877)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: J2SE 5.0 New Features

Author: Administrator

Date: 02 October 2005 06:00:00 +01:00 or Sun, 02 October 2005 06:00:00 +01:00

Summary: 

J2SE 5.0 has been available for download since the end of 2004. This new release included many changes and enhancements to the Java platform such as speed and stability. Additionally, some changes were made to the Java language itself.

Body: 

J2SE 5.0 has been available for download since the end of 2004. This new release included many changes and enhancements to the Java platform such as speed and stability. Additionally, some changes were made to the Java language itself. These fairly major changes made to the language are:

  • Generics

  • Enhanced for loop

  • Annotations (sometimes called metadata).

  • Autoboxing and unboxing

  • Typesafe enumerations

  • Variable arguments (varargs)

  • Static imports

Using these new language features in your applications can have a big effect on your code, so this article aims to provide an overview of these new features so that you can start leveraging them in your code. As a Java developer I make extensive use of these features now and find that they bring the Java language much more upto date.

Getting the JDK

The latest version of J2SE can be downloaded from Sun's website if you are a Windows/Linux developer or from Apple's website if you are an Apple developer. I'm not going to provide details about how to install the JDK as this is primarily an article about the new J2SE 5.0 features. Before you start developing however, its worth checking that you have the correct version of Java installed. Running java -version should produce output similar to the following.

C:\>java -version
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode, sharing)

Generics

What are generics? Generics are akin to templates in C++ in that they allow developers to write type safe code that operates on different types of objects. This is very useful when dealing with collections as it is no longer necessary to cast objects to specific types when extracting them from collections. This therefore eliminates the potential for getting ClassCastExceptions and makes code much easier to read.

In this trivial example, consider a collection of Strings (it doesn't have to be strings however, you could have a collection of any type of object). Prior to Java 5, if you wanted to extract the contents of a collection, you would use code such as that below:

import java.util.*;

public class Generic {

  public static void main(String[] args) {
  // Create a collection and add some items to  
  // it.
    Collection languages = new ArrayList();
    languages.add("Java");
    languages.add("C#");
    // Now get the items from the collection.
    Iterator iterator = languages.iterator();
    while (iterator.hasNext()) {
      System.out.println(
         (String)iterator.next());
    }
  }
}

Notice that to extract objects from the collection, we have to explicitly cast the retrieved objects to be Strings (or whatever class the collection consists of), potentially allowing us to get the dreaded ClassCastException if we had inadvertently added the wrong type of object to the collection in the first place. Also, its difficult to see from looking at the code what the collection contains. If there was an API method like the following, what exactly would the collection contain?

public doStuff(Collection items)

Using generics, our simple application can be re-written to get rid of the cast and made type safe.

import java.util.*;

public class Generic2 {
  public static void main(String[] args) {
  // Create a collection and add some items to 
  // it.
    Collection<String> languages = 
       new ArrayList<String>();
    languages.add("Java");
    languages.add("C#");
    // Now get the items from the collection.
    Iterator iterator = languages.iterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}

You can see that the collection has been explicitly declared to contain only String objects. Also note, that there is no cast required to extract items from the collection. The VM knows exactly what type of object is in the collection and knows how to return it to the calling application. If we tried to put something into the collection that isn't of the required type (in our small example, anything other than a String), then the code will simply fail to compile.

If we now re-wrote our rather obscure method doStuff, it may look something like the following. Here we can see exactly what type of object the collection contains.

public doStuff (Collection<String> items)

Enhanced for Loop

The enhanced for loop construct available in Java 5 allows us to refine this code even further and remove the need for using the Iterator to loop through the collection. This construct allows our simple application to be re-written, yet again, as:

import java.util.*;

public class Generic3 {
  public static void main(String[] args) {
    // Create a collection and add some items
    // to it.
    Collection<String> languages = 
       new ArrayList<String>();
    languages.add("Java");
    languages.add("C#");
    // Now get the items from the collection.
    for (String language : languages) {
      System.out.println(language);
    }
  }
}

This new construct is declaring that the code should loop through each entry in the collection languages. Each entry in the collection will be declared as a String called language which is then printed out to the console.

Hopefully you'll agree that these new features of Generics and the enhanced for-loop allow Java developers to write cleaner and safer code.

Annotations

Annotations provide a new feature to the Java language that potentially allow a vast amount of time to be saved when developing applications. They've been available in C# from the beginning and are now available to Java developers.

Annotations allow developers to add "hints" into their code (in a similar fashion to Xdoclet or JavaDoc tags) that the compiler can interpret at compile time. This allows the build process to do a variety of things such as produce artifacts that would otherwise have to be manually created, or to check that code complies with certain criteria.

There are 3 annotations that are supplied with J2SE 5.0, but developers have the ability to write additional annotations if they desire. These 3 basic annotations are @Override, @Deprecated and @Suppress.

@Override is applied to methods and is used by the compiler to check that overridden methods are declared correctly. A simple example of this would be to apply it to the toString() method of a class. @Override checks that the method to which it is applied correctly overrides its parent object. If the method is overridden incorrectly (e.g. it is spelt incorrectly or has the wrong signature) then a compile time error will be generated.

public class Annotation1 {

  @Override
  public String toStrng() {
    return "...";
  }

}

In this code fragment above, the method toString() has been declared incorrectly, e.g. public String toStrng() - note the deliberate spelling mistake. The @Override tag causes an error to be issued at compilation time.

C:\>javac Annotation1.java
Annotation1.java:3: method does not override a method from its superclass
        @Override
         ^
1 error

@Deprecated is applied to methods in a similar fashion to @Override. This annotation will cause a compiler warning to be issued if a deprecated method is used. Finally, @Supress is used to tell the compiler to suppress specified warnings.

The use of annotations is particularly of importance in the J2EE arena and is becoming more important in the strive to make J2EE easier. A couple of examples of this are Webservices (JAX-WS 2.0) and Enterprise Java Beans (EJB 3). The J2EE 1.4 way of creating web service and EJBs involves creating several different interfaces and various verbose XML configuration files that describe the webservices and EJBs being developed. With JAX-WS annotations, it will be possible to declare that a class should be exposed as a web service simply by putting a @WebService annotation before the class declaration. With EJBs its very similar. To declare a class as a stateless session bean is simply a matter of putting the @Stateless annotation before the class declaration. Of course there are more options that can be added into web services and EJBs to control their behaviour, but the fundamental principal is that all these options can be specified in code as annotations.

Autoboxing / Unboxing

Autoboxing and unboxing allows Java code to automatically convert between the basic primitive types (int, long, double etc) and their class equivalents (Integer, Long, Double etc.) and vice-versa. Prior to Java 5, if you needed to convert an Integer to an int, the code required would look something like

public class Autoboxing {
  public static void main(String[] args) {
    int value = 10;
    Integer newValue = new Integer(value);
    Autoboxing ab = new Autoboxing();
    ab.doStuff(newValue);
  }
  public void doStuff(Integer value) {
    System.out.println(value);
  }
}

In this code, the wrapper class newValue has to be directly instantiated from the varible value to be passed into the method. With Autoboxing, this is no longer required as the int will be converted into an Integer for us:

public class Autoboxing2 {
  public static void main(String[] args) {
    int value = 10;
    Autoboxing2 ab = new Autoboxing2();
    ab.doStuff(value);
  }
  public void doStuff(Integer value) {
    System.out.println(value);
  }
}

Static Import

Static imports are probably one of the least used features available to Java 5. They allows you to specify static variables in another class without having to specify the fully qualified name of the class being imported. Members can be statically imported into a class using the import static construct.

import static my.class.static.member;

Summary

Java 5 introduced new language features that allow developers to write code that is more robust whilst at the same time reducing the amount of boiler-plate code that needs to be written. If you're new to Java or are still using JDK 1.4, then its worth while investigating all the new features provided in Java 5.

Notes: 

More fields may be available via dynamicdata ..