New Features in Java 5.0

1) Introduction

Java 5.0 comes with a bunch of useful features. In this article, we are going to have an overview of the features like Enhanced for-loop, Variable Arguments, Static Imports and Enumerations. Apart from these features, we have already published other notable features in Java 5.0, auto boxing, generics and annotations. If you are interested in receiving the future Java mails, please subscribe here.

Enhanced For loop

We will cover the usage of Enhanced for-loop in this section. This is also referred to as for-each loop. The following code shows how to iterate over the elements in a Collection using the traditional Iterator interface.
ForEachTest.java

package foreach;

import java.util.*;

public class ForEachTest
{
	public static void main(String[] args)
	{
		List numbers = new ArrayList();
		numbers.add(1);numbers.add(2);numbers.add(3);

		Iterator numbersIterator = null;
		for(numbersIterator = numbers.iterator(); numbersIterator.hasNext();)
		{
			System.out.println(numbersIterator.next());;
		}
	}
}

Though the goal of the above program is traversing over the elements in the list collection, we are depending on the Iterator API to achieve this. A replacement to the Iterator is the usage of Enhanced for-loop, through which it is possible to have a short and a neat code like this,

for(Integer number : numbers)
{
	System.out.println(number);
}

Let us see how the above syntax is used to traverse over the collection. The expression before the symbol ':' is a declaration statement which declares an Integer object called number for holding the individual element from the collection. The expression that follows after the symbol must be a Collection type whose elements can be iterated. Precisely, this type must implement an interface called java.util.Iterable which has a single method called iterator(). During compile-time, the compiler translates the above code which looks very similar to the following,

Iterator intIterator = numbers.iterator();

for(intIterator.hasNext();)
{
	System.out.println(intIterator.next());
}

Even it is possible to apply this new syntax for type Arrays. So, the following code is perfectly legal and it compiles fine.

int [] numbers = {10, 20, 30, 40, 50};

for(int num : numbers)
{
	System.out.println(num);
}

The enhanced for-loop is just a convenience from the programmer’s point of view for iterating over the Collection. But the usage of this loop has some dis-advantages. The first one out of the two is that step-value cannot be incremented. For example, it is not possible to traverse the first element and then the thirth element and so on. And the second dis-advantage is that backward traversal is not possible.

Variable Arguments

Among the new features added in Java 5.0, Variable Arguments (var-args) is one of the coolest features. Before getting into this, let us see the reason in action for introducing such a feature like this. The following code snippet shows the addition of two numbers being done in the testAdd() method.
VariableArgumentsTest.java

package varargs;

public class VariableArgumentsTest
{
	static void addTest(String message, int a, int b)
	{
		int result = a + b;
		System.out.println(message + result);

	}

	public static void main(String[] args)
	{
		addTest("Addition Result is ", 10, 20);
	}
}

Consider that we want the addTest() method to add three numbers. Now, we introduce a third parameter called c in the method definition like this,

static void addTest(String message, int a, int b, int c)
{
	int result = a + b + c;
	...
}

Or we can have an overloaded method that is defined with three parameters and have the original implementation there. If the number of parameter values that are going to be passed for the addTest() method goes on increasing, then it requires change in the existing code or possibly the addition of new overloadeded methods. The way to get over this is by using a variable arguments. Internally a variable argument is maintained as an array that can hold zero or one or more arguments of the same type. Following code snippet shows the declaration of variable arguments.

static void addTest(String message, int... numbers)
{
	int result = 0;
	for(int num : numbers)
	{
		result = result + num;
	}
	return result;
}

Note that the type (int) is followed by three dots (often called ellipsis) and then the variable argument name. With such a declaration in hand, it is now possible to invoke the method as shown below.

addTest("Addition Ressult", 10, 20);     -> addTest("Addition", new int[]{10,20});
addTest("Addition Ressult", 10, 20, 30); -> addTest("Addition", new int[]{10,20, 30});
addTest("Addition Ressult");             -> addTest("Addition", new int[]{});

All the above styles are allowed as they are internally represented as arrays. There are two major constraints in the usage of variable arguments. The first thing is a method is allowed to carry only one variable argument type. The other constraint is that a variable argument type can appear only as the last parameter in a method definition. The following shows the legal and illegal usage of variable argument types.

static void test(int... a, String... b) -> Invalid, more than one variable argument type.
static void test(int... a, int... b)    -> Invalid, more than one variable argument type.
static void test(int... a, int b, int c)-> Invalid, Variable argument type must be the last parameter.
static void test(int a, int... b, int c)-> Invalid, Variable argument type must be the last parameter.
static void test(int a, int... b)       -> This is legal.
static void test(int... a)              -> This is also legal.

Static Imports

Static Imports is all about importing all the static Entities – like static classes, static methods and static objects and directly accessing them in code. For example, let us consider that you have a class like this,
StaticTest.java

package staticimport;

public class StaticTest
{
	public static final Object STATIC_OBJECT = new Object();

	public static Object getStaticObbject()
	{
		return STATIC_OBJECT;
	}

	public static class StaticClass
	{

	}
}

The above class is in a package called staticimport and it has a public static object called STATIC_OBJECT, a static method called getStaticObject() and a static inner class called StaticClass. Now let us see how to make use of static imports for accessing these static objects directly. Consider the following client program,
StaticTestClient.java

package staticimport.client;

import static staticimport.StaticTest.StaticClass;
import static staticimport.StaticTest.getStaticObbject;
import static staticimport.StaticTest.STATIC_OBJECT;

public class StaticTestClient {

	public static void main(String[] args) {

		System.out.println("Usage of a static class");
		StaticClass staticClassObject = new StaticClass();

		System.out.println("Usage of a static method");
		Object fromAStaticMethod = getStaticObbject();

		System.out.println("Usage of a static object");
		Object someStaticObject = STATIC_OBJECT;

	}
}

If you note the syntax of static imports, the static keyword follows after the import keyword. Only Static classes, static methods and static objects can be imported in this manner. Suppose, if you try to import a type that is not static, then the compiler will warn you telling that “The import cannot be resolved”, though it should give a descriptive warning telling that the type you are trying to import something which is not static.
Following example makes use of the APIs in the java packages. More specifically it imports all the static objects (members, objects and static classes) defined in System and Math class.
StaticTest.java

package staticimport.client;

import static java.lang.Math.*;
import static java.lang.System.*;

public class StaticTest {

	public static void main(String[] args)
	{
		gc();
		out.println("Testing static object");
		out.println("max of 10 and 20 is " + max(10, 20));
	}
}

5) Enumerations

Let us conclude this article by having a look at Enumerations (or Enums). In Java, Enum is a type, like a class or an interface. If Classes are used to represent objects, interfaces for behavior, then Enumerations are used to define range-based constants. For example, consider the following class that will calculate the population of a country when given the country name.
PopulationCalculator.java

package enums;

public class PopulationCalculator
{
	public static double calculatePopulation(String countryName)
	{
		double population = 0.00;

		if(countryName.equals("India"))
		{
			// Set Indian population here.
		}else if (countryName.equals("Australia"))
		{
			// Set population for Aussies here.
		}else if (countryName.equals("England"))
		{
			//Set population value for England here.
		}
		return population;
	}
}

The problem in the above code is with the input parameter countryName. Since the countryName is represented as a string, care should be taken in the very first line to ascertain the availability of such a country. What if the client passes something like “ABCDEF” or an empty string (“”) or even null for the country name? In all these cases, we end up in some kind of un-expected results at the run-time. We would feel that it would be better if the same error is captured during the compile-time itself. Here comes the concept of Enum which is any other type like Object, String or some other thing.
Following is the declaration of Enum called Country which takes the possible values of India, Australia and England.
Country.java

package enums;

public enum Country
{
	INDIA,

	AUSTRALIA,

	ENGLAND,

}

The keyword enum precedes the name of the Enum, in this case Country. Note that declaration of the various country names like India, Australia and England separated by commas. Internally, an Enum is represented by a class and the objects within it will be treated as public, static and final. So the above Country enum will internally look like this,
Country.java

package enums;

public class Country extends java.lang.Enum
{
	public static final Country INDIA = new Country();

	public static final Country AUSTRALIA = new Country();

	public static final Country ENGLAND = new Country();

}

Note that by default all the Enum classes extends java.lang.Enum class. And the restriction is that they cannot be extended. So Enums are implicitly treated as final classes, even though they can implement Interfaces. Now, let us modify the above Population Calculator class to make use of Country Enum instead of a string. Following is the code for the same.
PopulationCalculator.java

package enums;

public class PopulationCalculator
{
	public static double calculatePopulation(Country country)
	{
		double population = 0.00;

		if(country.equals(Country.INDIA))
		{
			// Set Indian population here.
		}else if (country.equals(Country.AUSTRALIA))
		{
			// Set population for Aussies here.
		}else if (country.equals(Country.ENGLAND))
		{
			//Set population value for England here.
		}
		return population;
	}
}

Now, since the calculatePopulation() method is accepting a type Country which is of type Enum, the client can pass only any of the defined Object in the Enum, thereby ensuring type-safeness. Since all custom Enum classes extend java.lang.Enum class, some of the useful methods like Enum.values() and Enum.ordinal() are automatically available to the Country Enum class. Have a look at the following sample class.
EnumTest.java

package enums;

public class EnumTest {

	public static void main(String[] args) {

		Country[] countries = Country.values();

		for(Country country : countries){
			System.out.println(country.toString() + ":
				Oridinal Value->" + country.ordinal());
		}

}

The call to Country.values() will return an Array of Country values with the values defined within the Country Enum. The method Country.ordinal() will return an index that tells the position of the enum object.

Conclusion

This article covered some of the new features available in Java 5.0 like Enhanced For loop, Variable Arguments, Static Imports and Enumerations along with plenty of samples. Each of these new features finds its appropriate usage based on the requirements. Applications can make use of the new features in an optimal way and thereby ensure that the code is simple and efficient.
Javabeat has published many of the good articles related to Java 1.5 version. This list will help you to learn some of the notable features introduced with the version 1.5, please have a look on these articles when time permits. Don’t forget to leave your feedback on the comments section. This helps us to provide better content for you.

The above article would provide the higher level of understanding on each concept. There are many other great features introduced in the Java 1.5 version. Hope this helps you!!

If you would like to receive future mails on Java articles, please subscribe here.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Comments

  1. Dhanaiah says:

    Very good examples. Try to add other features as well. I found few more in Java 5 (J2SE 5.0/JDK 1.5) New Features with Examples

  2. Dhanaiah says:

    Very good examples. Try to add other features as well. I found few more in Java 5 (J2SE 5.0/JDK 1.5) New Features with Examples

Trackbacks

  1. [...] Java 5.0 Features [...]

  2. [...] introduced in Java 5.0 (Read: New features in Java 5.0) allows switching to be done based on the enums values. It is one of the greatest new features [...]

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better