Sunday, November 16, 2008

Ease of Dev in Java 5: Generics, Autoboxing, Static Import, Enhanced for, Annotation, & Typesafe enum


Java 5 features for easier dev: Generics, Autoboxing/Unboxing, Static Import, Enhanced for, Typesafe enums, Annotaion/Metadata

I had to give a presentation on Java 5.0 few weeks back in my company and during that time I went through an interesting
interview (taken sometime in 2003) of Joshua Bloch who touch based on the six popular new features of Java 2 Platform, Standard Edition 5.0 (also knwon as J2SE 5.0) including Generics, Autoboxing, Static Imports, Annotations, Enhanced for loop, and Typesafe Enums. He talked about how these new features are going to be accepted by the developers worldwide and how actually will these features make application development in Java easier, safer, and more robust. Bloch is an architect at Sun Microsystems and he has been involved in the design and implementation of several Core Java features including the highly regarded Collections Framework and the java.math package. He has authored the Jolt award winning book named "Effective Java". His interview can be found here.

Before we move ahead let's discuss what the six major new features (aimed towards ease of development) introduced in Java 5.0 are all about.

  • Generics: this feature is used to ensure compile-time safety for Collections and eliminates the need for having the casts. The feature guarantees the code using Collections won't throw the infamous runtime exception named 'ClassCastException' as such cases can be detected at compile-time itself if the programmer uses Generics. A big relief, isn't it?
  • Autoboxing/Unboxing: this feature is used to make the automatic casting possible between the primitive data types and their corresponding wrapper data types. For example: an 'int' can now be assigned to a reference of type 'Interger' and vice-versa. The compiler automatically takes care of this.
  • Static Import: remember using Interfaces just for using static constants in Java programs. Interfaces are not meant for that, instead they should be used for defining types. Using them just for the sake of using constants not only defeats the actual meaning of interfaces, but it also makes the code less flexible as implementing an interface is a public contract and even if you plan not to use the constants defined in the interface in the newer implementations of the class then also you got to maintain the contract as the clients might have used the interface as a data type for the implementing class in their code. Static import actually imports all the static members of a class/interface making them available to be used with their simple names and thus you can avoid implementing the interfaces for using the constants.
  • Enhanced for-loop: this feature makes the for-loop more compact. The iterators now don't need to be explicitly checked for boundary conditions.
  • Annotations/Metadata: this feature helps the programmer by letting the tools generate the obvious code just by supplying the corresponding annotation tags. It makes the programming more "declarative" in nature.
  • Typesafe enums: most of the shortcomings of the enums which previously require lot of coding around their use to ensure safe usage have now been resolved in this new version of enums which are completely Typesafe and additionally they can be used with switch statement as well.

Some of the interesting questions taken from his interview are listed below:-


Question: How Java 5.0 will help making Java an easier and more effective language to work with?


Answer: Bloch summarizes the answer to this question with two main points saying that Java 5.0 will help shifting the
responsibility of writing the boilerplate code from the programmer to the compiler and he believes that the whole will be greater than the sum of its parts. Generics, Autoboxing, Enhanced for-loop are the features which shift quite a lot coding responsibility from the programmer to the compiler. Humans are error prone and hence shifting the responsibility ultimately not only speeds up the development, but also makes the code more reliable and secure.

Since all the features have been thought about keeping the others (and those which are already existing) in mind and hence
the designers have exploited the positives of all possible features during the design and implementation of these features. This makes the overall benefit even more than what these features could have contributed while having been designed in isolation. For example: Generics, Autoboxing, and Enhanced for-loop make such a fabulous combination when used together and this results into one of possible scenarios where we actually realize the power of these features, especially when they are used together. One example taken from his interview which nicely shows how well can the these features be combined to get cleaner, safer, and easier to write code is as follows:

The example counts the frequency of words supplied at the command line. There are two versions, the former without the use of
any Java 5.0 features and the latter beautifully uses Generics, Autoboxing, and Enhanced for-loop.


public class Freq {
private static final Integer ONE = new Integer(1);

public static void main(String args[]) {
// Maps word (String) to frequency (Integer)
Map m = new TreeMap();

for (int i=0; i<args.length; i++) {
Integer freq = (Integer) m.get(args[i]);
m.put(args[i], (freq==null ? ONE :
new Integer(freq.intValue() + 1)));
}
System.out.println(m);
}
}



As you can easily figure out that the above code counts the frequency by having a TreeMap where the keys are the words and
the corresponding values are their frequencies. At the first occurrence of the word the value is set to ONE and subsequently it increases by 1 on every other occurrence of the same word. Now see the same program using the three new features of Java 5.0:


public class Freq {
public static void main(String args[]) {
Map m = new TreeMap();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
System.out.println(m);
}
}



Clearly it's far more readable and easier to understand, write, and maintain than the former version.


Question: Will the changes be hard for developers to adapt to?

Answer: Bloch says that it won't be tough for the developers to adjust to the changes. Generics will probably be little tricky in the beginning as the declaration will now require more info to be supplied.

Considering the benefits of Generics these adjustments don't really bother the programmers. In fact, once used to the feature
they start realizing that how the readability and cleanliness of the code has tremendously improved. No explicit casting required and no fear of the runtime ClassCastException now :-)

Question:
How does the "enhanced for-loop" help the developers?


Answer:
This feature allows the programmers to forget about taking care of the iterators obtained from the Collections. The
compiler automatically does that and it ensures that the iterators for each element in the Collection they have been obtained from. Bloch says that having two extra keywords "foreach" and "in" could have made this even more readable and understandable, but that might have compromised with the compatbility with the earlier versions as the clients might have used these two words as identifiers in their programs.

Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


1 comment:

Anonymous said...

Good write up. Full of so much of info still very lucid. Thanx!