Making packages

Java provides a way to collect the definitions of related classes and interfaces, each in its own .java file, into a package. There are two potential advantages in making a package:

  1. If the definition of a class, an interface, or a field or method within a class does not begin with an explicit access specifier (public, protected, or private, other classes in the same package can refer to it without either explicitly importing it or using a fully qualified name (which includes the name of the package)..

  2. All of the classes and interfaces in the package can be imported with a single import statement in which .* is added at the end of the name of the package.

A file containing the definition of a class may contain a package statement that indicates the package to which the class belongs. The package statement consists of the keyword package, an identifier (possibly broken up by dots), and a semicolon. For instance, the package statement

package foo.bar;

in a file containing the definition of a class Baz would indicate that the class belongs to the package foo.bar and that its fully qualified name is foo.bar.Baz.

A Java source-code file contains at most one package statement, which must precede everything in the file except comments and whitespace. If the file contains no package statement, the class is assigned to the anonymous package, which contains otherwise unpackaged classes defined in files located in the same directory.

As a convention for avoiding duplication of package identifiers, the authors of Java suggest that you name your packages by lining up the components of your e-mail address, in reverse order, separated by dots, and then attaching some word that describes the nature of the classes in the package. For instance, George Spelvin, a typical Grinnell student, might give the name edu.grinnell.spelvin.options to his package of classes that parse and store command-line options.

To enable the Java run-time system to find the compiled classes in a package that you write, you must define an environment variable, CLASSPATH, before running java. The value of this environment variable should be a string of one or more directories, separated by colons. To tell Java to look in his current working directory and in /home/spelvin/Java-packages for compiled class files, George would give the command

setenv CLASSPATH .:/home/spelvin/Java-packages

(A few of you may be using a shell other than the C shell, /usr/bin/csh as your command-language interpreter. If so, your command may look slightly different. For the Bourne and bash shells, it would be CLASSPATH=.:/home/spelvin/Java-packages, for instance.)

Even with the help of the class-path, the Java run-time system won't be able to find your files unless they are located in a subdirectory that corresponds to the name of the package, which each dot in the package name corresponding to a descent into a subdirectory. So the files for George's edu.grinnell.spelvin.options package would actually be placed in a subdirectory named /home/spelvin/Java-packages/edu/grinnell/spelvin/options. Both the .java and the .class files belong there.

To run the main method in the Tester class in his edu.grinnell.spelvin.options package, George can give the command

java edu.grinnell.spelvin.options.Tester

or, if his current working directory is /home/spelvin/Java-packages/edu/grinnell/spelvin/options, simply java Tester. In each case, java consults the class path to determine where to look for the application.

When defining a new class that uses this same Tester class, George writes

import edu.grinnell.spelvin.options.Tester;

to import it. Again, the Java compiler javac will find the class definition only if the value of George's CLASSPATH environment variable includes the appropriate starting directory (in this case, /home/spelvin/Java-packages).


created October 20, 1999
last revised October 20, 1999

John David Stone (stone@cs.grinnell.edu)