1 July 2005

Tip: import explicitly

No, I'm not talking about swearing cargo handlers, I'm talking about the Java packaging system.

Code written in enterprise Java is split into different packages. The idea of this is to separate classes so that those in different packages typically aren't aware of one another. Classes in different packages only interact when one class explicitly imports another.

Sun's specification defines technically what an import does:

An import declaration allows a named type to be referred to by a simple name that consists of a single identifier. Without the use of an appropriate import declaration, the only way to refer to a type declared in another package is to use a fully qualified name.

That is, rather than typing out a massive classname in full like net.mattryall.weblog.data.QueryParameter every time you use it, you can just refer to it as just QueryParameter. All you have to do is "import" the other class in full once at the top of your code.

Where this becomes dangerous is that Java allows you to import a huge number of classes with a single statement. You do it by importing a package name and a wildcard, which means import all the classes in that package. It looks like this:

import java.text.*;

There are two problems with this approach.

First, when you see an unqualified class name used in a file with a wildcard import, you've got no way of determining whether it refers to a class in your current package, or in one of the (often many) wildcard packages imported at the top. A clever IDE can tell you, but manually you have to go and look at each class in each included package.

Second, having only a few import statements looks like there are just a few dependencies for your code. But when these lines contain wildcards, the class could interact with a multitude of different classes in the packages mentioned. Understanding the dependencies of a class is important in understanding the function of the class. Having an import list with wildcards obscures the dependencies, and therefore obscures the function of the class.

The argument in favour of import wildcards is that it simplifies your code when importing many classes from the same package. The problem is, if you're importing many classes from the same package, there's already a problem! Perhaps your class should move to the other package, or perhaps you need to split the responsibilities of this class because it's doing too much. Either way, if the number of classes your class interacts with number much beyond 10, there's something amiss.

What all this means is, for maintainable Java code, it's better to avoid wildcard import statements. Or as a tip, import explicitly.