Thursday, January 19, 2006

Java 5 Static Imports

Java 5 introduces the static import feature for allowing better access to the static members of a class. According to sun, this feature helps programmers avoid the "constant interface antipattern".

The problem:
It is a general practice to declare all your constants as public static final members of an interface and access them throughout the application. For ex.

package mypackage;
public interface Constants {
public static final double PI = 3.14;
public static final double PHI = 1.61803399;
public static final int RAD = 50;
}

These constants may be accessed from another class thus

package mypackage;
import mypackage.Constants;
public class StaticImportTest {
public static void main(String args[]) {
double area = Constants.PI * Constants.RAD * Constants.RAD;

System.out.println(area);
}

}

(you can always use the constants and methods of java.lang.Math for such operations)

While this is an correct implementation, most programmers would prefer a cleaner approach to this where you can write:

double area = PI * RAD * RAD;

To achieve this, programmers tend to implement the interface, so that they can avoid typing the interface name and also have readable code. The problem with this approach is that:
  1. You are making the constants in the interface a part of the contract of your class, so any client using your class can access the constants. If they do, then any change in the constants will mean that the all the clients have to be recompiled.
  2. More importantly, you are making the constants a part of your class' API, which exposes your implementation details.

The solution:
Java 5.0 provides a solution for this problem in the form of static imports. Now you can import all the constants in the interface using a single "import static" statement thus:

import static mypackage.Constants.*;
package mypackage;
import static mypackage.Constants.PI;
import static mypackage.Constants.RAD;
public class StaticImportTest {
public static void main(String args[]) {
double area = PI * RAD * RAD;

System.out.println("2 " + area);
}

}

Although this avoids the "Constant Interface Antipattern" it also comes with some problems which can be avoided by a little careful programming:
  1. If you have multiple static imports, it becomes difficult for the reader to understand where the constant is coming from.
  2. You may end up having naming conflicts in your program.

So, here are a couple of things to remember while using static imports

  1. Always import the full path of the constant, without the wildcards. For ex:

    import static mypackage.Constants.PI;
  2. Use static imports to improve readability not to avoid typing too much.
** The code was tested on Windows XP with JDK1.5.0_06**

No comments:

Post a Comment