Wednesday, September 29, 2010

JDK 1.5 Features:


· Generics—Provides compile-time type safety for collections and eliminates the need for casting every time you get an object out of Collections.

· Enhanced For loop—Eliminates error-proneness of iterators.

· Autoboxing/unboxing—Eliminates need of manual conversion between primitive types (such as double) and wrapper types (such as Double).

· Typesafe enumsProvides all benefits of the Typesafe enum pattern.

· Static import—Eliminates the need for using class names prior to using the static member variables of other classes. This will make the code a bit neater.

· Metadata—Allows programmers to avoid writing boiler plate code and gives the opportunity for declarative programming.


Let's discuss each feature in detail and take a look at some examples.

Generics
Generics is one of the coolest features of JDK 1.5. By introducing generics, we will have compile-time type safety and possibly fewer ClassCastExceptions during run time. In JDK 1.5, you can declare the type of objects one collection will accept/return. In JDK 1.4, creating a List of employee names requires a collection object like the following statement:
List listOfEmployeeName = new ArrayList();

In JDK 1.5, you would use this statement:
List listOfEmployeeName = new ArrayList();

The cool part is that if you try to insert something that's not a string, you will find out at compile time and then you can fix the problem. Without generics, you discover such a bug when your customer calls and tells you that the program you shipped crashed with a ClassCastException.

The other cool thing is that you don't have to cast when you get an element out of the collection. So instead of this type of statement:
String employeeName = ((String) listOfEmployee.get(i));

It's simply:
String employeeName = listOfEmployee.get(i);

Casting objects without knowing the type of object is not good, and more importantly, it can fail at run time. Suppose the user accidentally passes in a collection that contains string buffers rather than strings.


Now it's clear from the method signature that the input collection must contain only strings. If the client tries to pass in a collection of string buffers, the program won't compile. And notice that the method doesn't contain any casts. It's one line shorter and, once you get used to reading generics, it's clearer too.

Enhanced For Loop
Here's the syntax for the For loop in the current version of the JDK:
void printAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
Employee emp = (Employee)i.next();
System.out.println(emp.getName());
}
}

Now here's the same method with an enhanced For statement:
void printAll(Collection c) {
for (Object o : c)
System.out.println((TimerTask)o).getName());
}

In this For loop, you should read the ":" as "in," so the example reads "for Object o in c". You can see this For loop has more readability.

Autoboxing and unboxing
In Java, we have primitive data types and wrapper classes around these primitive types. Most often programmers need to convert one type to another. Take a look at the following code.

int n=10;

Integer age= new Integer(30);

Integer ageAfterTenYear= new Integer(age.intValue +10);


Notice how messy the inner-loop code that calculates ageAfterTenYear looks. Now take a look at the same program rewritten with autoboxing, as shown

          int n=10;
         Integer age= new Integer(30);
         Integer ageAfterTenYear= age +10;

One thing worth noting: Previously, if you unboxed Null, it became zero. In this code, the compiler would automatically convert Integer to int and add 10 to it, then convert that back to Integer.

Typesafe enums
Typesafe enums provide the following features:

· They provide compile-time type safety.

· They are objects, so you can put them in collections.

· They are implemented as a class, so you can add some methods.

· They provide a proper name space for the enumerated type.

· Their printed values are informative—if you print an int enum, you just see a number, which may not be that informative.


Example 1:
enum Season { winter, spring, summer, fall }

Example 2:
public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}

Static imports
Static imports make code more readable. Currently, you use constants defined in other classes, like this:
import org.yyy.pkg.Increment;

class Employee {
public Double calculateSalary(Double salary{
return salary + Increment.INCREMENT * salary;
}
}

But with static import, we can use those constants without providing the name of the class prior to constant name, like this:
import static org.yyy.pkg.Increment;

class Employee {
public Double calculateSalary(Double salary{
return salary + INCREMENT * salary;
}
}

Note that we are able to call the INCREMENT constant without using the class nameIncrement.

Metadata
The metadata feature is focused on making a developer's life simpler with the support of tools provided by vendors. Take a look at the following code

public interface EmployeeI extends Java.rmi.Remote {

public String getName() throws Java.rmi.RemoteException;

public String getLocation () throws Java.rmi.RemoteException;

}

With metadata support, you can write the code in Listing E like this:
import org.yyy.hr;

public class Employee {
@Remote public String getName() {
...
}
@Remote public public String getLocation() {
...
}
}

As you can see, all the boilerplate's code is gone.