organic thoughts

seemingly random and unorgainzed bits of information

10.11.2005

Better Development with Java 5

Sun released the Tiger edition of the JDK late last year (Sept 2004). The release itself was not too much of a groundbreaking event (the JDK was already in beta for months). More significantly, to me, are the newly released IDE's that support the developer-friendly features found in Tiger. Eclipse 3.1 and NetBeans 4.0 provide supports for new language features including Generics, For-Each loop, Enumerated Types, etc.


In this post, I will explore some of the more prominent features in Tiger that will
likely effect how developers code. It is evident, that the Java engineers are pushing the language toward a more agile direction where the compiler and the runtime environment will provide smarter assistance to developers and increase its user-friendliness through
new constructs such as auto-boxing and for-each loop.


Generic Types (Generics)

Prior to Java 5, developers creating API's used the super class Object whenever their code needed to support reference to classes whose types were not known until integration-time. This was convenient, but went against the very essence of Java's type safety abilities. Java 5 introduced Generic Types (or Generics) which is a way to dynamically enforce type safety in places that can accept references to any type.

The best way to experience generics is with the java.util.Collection API. The entire API has been re-written to support generic types. The Collection API is designed to maintain a collection of any type of objects. In previous version of Java, objects retrieved from a collection must be cast to its original type to be useful. However, generics lets you specify which type the collection will accept.

Code Example:


public class GenericTypeDemo {
public static void main(String[] args){
int size = 10;

List<Integer> values = new ArrayList<Integer>(size);
for(int i = 0; i < size; i++){
values.add(new Integer(i + 2));
// The following line will cause error. The compiler
// will enforce type constraint for the specified
// Integer type.
/* values.add("Text Here"); */
}
}


}
In the example, The List being passed to the method can only contain objects of type Integer. The <> (angle bracket) notation provides hints to the compiler and it will enforce the type safety constraints during compilation. A good IDE will provide hints on type violations when using generics. You can generify your own API in a similar manner as the Collection API. However, that subject matter is way beyond this material. See the References section for more information.

Auto-Boxing / Auto-Unboxing

This feature is sure to save you many key strokes when converting from a primitive type to its object counter part and vice versa. The compiler will automatically generate the necessary code and call the proper methods for you.

Code Sample:


public class AutoBoxingDemo {
public static void main(String[] args){
int size = 10;
List<Integer> values = new ArrayList<Integer>(size);

// init values
for(int i = 0; i < size; i++){
values.add(i * 2); // auto boxing
}
// get total

int total = 0;
for(Iterator i = values.iterator(); i.hasNext();){
int val = i.next(); // auto unboxing
System.out.println(val);
total = total + val;

}
System.out.print("Total = " + total);
}

}
Enumerated Types

This long-awaited feature has finally
made it in Java. An enumerated type (or enum) is a special class that
store constant values. Enums are compiled into singletons where only
one copy of the enumerated values are made available. The enumerated
values are constants and cannot be changed at runtime.


Code Sample 1:
public class EnumDemo {
public enum Operation {ADD,SUB,DIV,MUL}
public static void doOp(int val1, int val2, Operation op){
switch(op){

case ADD:
System.out.println(val1 + " + " + val2 + " = " + (val1 + val2));
break;

case SUB:
System.out.println(val1 + " - " + val2 + " = " + (val1 – val2));
break;

default:break;
}
if(op == Operation.MUL)
System.out.println(val1 + " x " + val2 + " = " + (val1 * val2));

if(op == Operation.DIV)
System.out.println(val1 + " div by " + val2 + " = " + (val1 / val2));
}

public static void main(String[] args){
int val1 = 5;
int val2 = 3;
doOp(val1,val2, Operation.DIV);
}
}

The enumeration type is a regular class. It can host fields, methods, and constructors. All enums have service methods such as values() which return an array of the enumerated types. Even sweeter, each enumerated constant in an Enum type can receive a class body that modifies the behavior of the constant dynamically. In the following example, I have attached behavior directly to the Enum constant.


Enum – Code Sample 2:
public class EnumDemo2 {
public enum Operation {
ADD,SUB,DIV,MUL;

public double calc(double op1, double op2){

double result = 0;
switch(this){
case ADD: result = op1 + op2; break;
case SUB: result = op1 - op2; break;
case DIV: result = op1 / op2; break;
case MUL: result = op1 * op2; break;

default:throw new IllegalArgumentException("Invalid Operator");
}
return result;
}
}


public static void main(String[] args){
double op1 = 12;
double op2 = 7;
Operation add = Operation.ADD;
System.out.println(add + " " + op1 + " to " + op2 + "=" + add.calc(op1,op2));

}
}
Variable Argument (VarArgs)

This new feature lets developers create methods that can accept a variable list of arguments. By providing a special argument signature, the compiler will create an array ofObjects that contain each argument.


Code Sample:
public class VarArgsDemo {

public static void logAction(Object...args){
System.out.print("WHEN: " + args[0]);
System.out.print(" LEVEL: " + args[1]);
System.out.println(" MESSAGE: " + args[2]);

}

public static void main(String[] args){
logAction(new Date(), 10, "No Action Taken");
// using the new printf which uses var args itself
System.out.printf("WHEN: %s LEVEL: %d MESSAGE: %s%n",
new Date(), 20, "Action Completed");

}

}
In the code sample above, method logAction() takes a variable argument list. The compiler automatically creates an array of objects that is made available to the method. If no arguments are passed to the logAction(), it will have an empty array. So, care must be taken to avoid ArrayIndexOutOfBoundsException.

Formatted Output

Java 5 has the new printf() which facilitates formatted output. Printf() makes use of the variable argument mechanism to allow to create c-style formatted output.

Code Sample:

See
VarArgs Sample.


This code sample prints out the same output as in the VarArgs example. The printf() function uses special formatters (see java.util.Formatter) as place holders for the values being printed. In this simple example, the %s will emit a string and the %d will emit a digit. The %n automatically emits the proper line break character based on the platform.


For-Each Loop

Another developer-friendly feature is the for-each loop. Here again, the compiler generate the code to create the index-based for-loop for array types or the iterator-style for-loop any type that implements the Iterable interface (Iteratorclass for instance).


Code Sample:
public class ForEachLoopDemo {
public static void main(String[] arsg){
// simple arrays

String[] cities = {
"Miami",
"New York",
"Tampa",
"San Antonio",

"Pueblo"
};
for(String city : cities){
System.out.println(city);
}


// collection
Set<Integer> values = new HashSet<Integer>(3);
values.add(12);
values.add(5544);
values.add(44);

for(Integer i : values){
System.out.println(i);
}

}
}


The For-Each loop simplifies the code and increase readability. There are instances, however, when you will not be able to use this convenient construct. When you need access to an array index (as in the case with multi-dimensional arrays), you will not be able to use the new For-Each loop. Also, if you need access to the iterator variable, you cannot use the For-Each loop.


Conclusion

These are just a small sample of the new features of JSE 5. There are new thread constructs provided as the Concurrency framework. There's a powerful metadata (or annotation) framework provided for tool developers. Enhancements have been made in the Swing API. And finally there are numerous management and JDK profiling features that will please any one who wants to look deep inside a running program.

Resources:


JDK 5 – Tiger Presentation
JavaPolis Dec 2004, Joshua Bloch and Neal Gafter –
http://www.javapolis.com/JP04DVDContent/talks/Tiger/index.html

J2SE 5 In A Nutshell – OnJava.Com, Calvin Austin, May 2004
http://java.sun.com/developer/technicalArticles/releases/j2se15/

Programming with the New Language Features in JSE 5.0, Qusay Mahmoud, 2004
http://java.sun.com/developer/technicalArticles/releases/j2se15langfeat/


Complete List of New Java 5 Features - http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html

IBM DeveloperWorks Articles,
http://www-128.ibm.com/developerworks/views/java/libraryview.jsp?search_by=taming+tiger:









<< Home

This page is powered by Blogger. Isn't yours?