Contents | Prev | Next | Index

CHAPTER 7

Packages


Java programs are organized as sets of packages. Each package has its own set of names for types, which helps to prevent name conflicts. A type is accessible (§6.6) outside the package that declares it only if the type is declared public.

The naming structure for packages is hierarchical (§7.1). The members of a package are class and interface types (§7.6), which are declared in compilation units of the package, and subpackages, which may contain compilation units and subpackages of their own.

A package can be stored in a file system (§7.2.1) or in a database (§7.2.2). Packages that are stored in a file system have certain constraints on the organization of their compilation units to allow a simple implementation to find classes easily. In either case, the set of packages available to a Java program is determined by the host system, but must always include at least the three standard packages java.lang, java.util, and java.io as specified in Chapters 20, 21, and 22. In most host environments, the standard packages java.applet, java.awt, and java.net, which are not described in this specification, are also available to Java programs.

A package consists of a number of compilation units (§7.3). A compilation unit automatically has access to all types declared in its package and also automatically imports each of the types declared in the predefined package java.lang.

A compilation unit has three parts, each of which is optional:

For small programs and casual development, a package can be unnamed (§7.4.2) or have a simple name, but if Java code is to be widely distributed, unique package names should be chosen (§7.7). This can prevent the conflicts that would otherwise occur if two development groups happened to pick the same package name and these packages were later to be used in a single program.

7.1 Package Members

A package can have members of either or both of the following kinds:

For example, in the standard Java Application Programming Interface:

If the fully qualified name (§6.7) of a package is P, and Q is a subpackage of P, then P.Q is the fully qualified name of the subpackage.

The subpackages of package java named lang, util, and io (whose fully qualified package names are therefore java.lang, java.util, and java.io) are a standard part of every Java implementation and are specified in Chapters 20, 21, and 22. Many Java implementations will include the entire set of java packages defined in the series of books The Java Application Programming Interface.

A package may not contain a type declaration and a subpackage of the same name, or a compile-time error results. Here are some examples:

The hierarchical naming structure for packages is intended to be convenient for organizing related packages in a conventional manner, but has no significance in the Java language itself other than the prohibition against a package having a subpackage with the same simple name as a type declared in that package. There is no special access relationship in the Java language between a package named oliver and another package named oliver.twist, or between packages named evelyn.wood and evelyn.Waugh. For example, the code in a package named oliver.twist has no better access to the types declared within package oliver than code in any other package.

7.2 Host Support for Packages

Each Java host determines how packages, compilation units, and subpackages are created and stored; which top-level package names are in scope in a particular compilation; and which packages are accessible.

The packages may be stored in a local file system in simple implementations of Java. Other implementations may use a distributed file system or some form of database to store Java source and/or binary code.

7.2.1 Storing Packages in a File System

As an extremely simple example, all the Java packages and source and binary code on a system might be stored in a single directory and its subdirectories. Each immediate subdirectory of this directory would represent a top-level package, that is, one whose fully qualified name consists of a single simple name. The directory might contain the following immediate subdirectories:


COM
gls
jag
java
wnj
where directory java would contain the standard Java Application Programming Interface packages that are part of every standard Java system; the directories jag, gls, and wnj might contain packages that the three authors of this specification created for their personal use and to share with each other within this small group; and the directory COM would contain packages procured from companies that used the conventions described in §7.7 to generate unique names for their packages.

Continuing the example, the directory java would probably contain at least the following subdirectories:


applet	
awt
io
lang
net
util
corresponding to the standard packages java.applet, java.awt, java.io, java.lang, java.net, and java.util that are defined as part of the standard Java Application Programming Interface.

Still continuing the example, if we were to look inside the directory util, we might see the following files:


BitSet.java										Observable.java
BitSet.class										Observable.class
Date.java										Observer.java
Date.class										Observer.class
Dictionary.java										Properties.java
Dictionary.class										Properties.class
EmptyStackException.java										Random.java
EmptyStackException.class										Random.class
Enumeration.java										Stack.java
Enumeration.class										Stack.class
Hashtable.java										StringTokenizer.java
Hashtable.class										StringTokenizer.class
NoSuchElementException.java										Vector.java
NoSuchElementException.class										Vector.class
where each of the .java files contains the source for a compilation unit (§7.3) that contains the definition of a class or interface whose binary compiled form is contained in the corresponding .class file.

Under this simple organization of packages, an implementation of Java would transform a package name into a pathname by concatenating the components of the package name, placing a file name separator (directory indicator) between adjacent components. For example, if this simple organization were used on a UNIX system, where the file name separator is /, the package name:

jag.scrabble.board
would be transformed into the directory name:

jag/scrabble/board
and:

COM.Sun.sunsoft.DOE
would be transformed to the directory name:

COM/Sun/sunsoft/DOE
In fact, the standard JavaSoft Java Developer's Kit on UNIX differs from the very simple discipline described here only in that it provides a CLASSPATH environment variable that specifies a set of directories, each of which is treated like the single directory described here. These directories are searched in order for definitions of named packages and types.

A package name component or class name might contain a character that cannot correctly appear in a host file system's ordinary directory name, such as a Unicode character on a system that allows only ASCII characters in file names. As a convention, the character can be escaped by using, say, the @ character followed by four hexadecimal digits giving the numeric value of the character, as in the \uxxxx escape (§3.3), so that the package name:

children.activities.crafts.papierM\u00e2ch\u00e9
which can also be written using full Unicode as:

children.activities.crafts.papierMâché
might be mapped to the directory name:

children/activities/crafts/papierM@00e2ch@00e9
If the @ character is not a valid character in a file name for some given host file system, then some other character that is not valid in a Java identifier could be used instead.

7.2.2 Storing Packages in a Database

A host system may store packages and their compilation units and subpackages in a database.

Java allows such a database to relax the restrictions (§7.6) on compilation units in file-based implementations. For example, a system that uses a database to store packages need not enforce a maximum of one public class or interface per compilation unit. Systems that use a database must, however, provide an option to convert a Java program to a form that obeys the restrictions, for purposes of export to file-based implementations.

7.3 Compilation Units

CompilationUnit is the goal symbol (§2.1) for the syntactic grammar (§2.3) of Java programs. It is defined by the following productions:

Types declared in different compilation units can depend on each other, circularly. A Java compiler must arrange to compile all such types at the same time.

A compilation unit consists of three parts, each of which is optional:

Every compilation unit automatically and implicitly imports every public type name declared in the predefined package java.lang, so that the names of all those types are available as simple names, as described in §7.5.3.

7.4 Package Declarations

A package declaration appears within a compilation unit to indicate the package to which the compilation unit belongs. A compilation unit that has no package declaration is part of an unnamed package.

7.4.1 Named Packages

A package declaration in a compilation unit specifies the name (§6.2) of the package to which the compilation unit belongs.

The package name mentioned in a package declaration must be the fully qualified name (§6.7) of the package.

If a type named T is declared in a compilation unit of a package whose fully qualified name is P, then the fully qualified name of the type is P.T; thus in the example:

package wnj.points;
class Point { int x, y; }
the fully qualified name of class Point is wnj.points.Point.

7.4.2 Unnamed Packages

A compilation unit that has no package declaration is part of an unnamed package. As an example, the compilation unit:


class FirstCall {
	public static void main(String[] args) {
		System.out.println("Mr. Watson, come here. "
									+ "I want you.");
	}
}
defines a very simple compilation unit as part of an unnamed package.

A Java system must support at least one unnamed package; it may support more than one unnamed package but is not required to do so. Which compilation units are in each unnamed package is determined by the host system.

In Java systems that use a hierarchical file system for storing packages, one typical strategy is to associate an unnamed package with each directory; only one unnamed package is available at a time, namely the one that is associated with the "current working directory." The precise meaning of "current working directory" depends on the host system.

Unnamed packages are provided by Java principally for convenience when developing small or temporary applications or when just beginning development.

Caution must be taken when using unnamed packages. It is possible for a compilation unit in a named package to import a type from an unnamed package, but the compiled version of this compilation unit will likely then work only when that particular unnamed package is "current." For this reason, it is strongly recommended that compilation units of named packages never import types from unnamed packages. It is also recommended that any type declared in an unnamed package not be declared public, to keep them from accidentally being imported by a named package.

It is recommended that a Java system provide safeguards against unintended consequences in situations where compilation units of named packages import types from unnamed packages. One strategy is to provide a way to associate with each named package at most one unnamed package, and then to detect and warn about situations in which a named package is used by more than one unnamed package. It is specifically not required-indeed, it is strongly discouraged-for an implementation to support use of a named package by more than one unnamed package by maintaining multiple compiled versions of the named package.

7.4.3 Scope and Hiding of a Package Name

Which top-level package names are in scope (§6.3, §6.5) is determined by conventions of the host system.

Package names never hide other names.

7.4.4 Access to Members of a Package

Whether access to members of a package is allowed is determined by the host system. The package java should always be accessible, and its standard subpackages lang, io, and util should always be accessible.

It is strongly recommended that the protections of a file system or database used to store Java programs be set to make all compilation units of a package available whenever any of the compilation units is available.

7.5 Import Declarations

An import declaration allows a type declared in another package to be referred to by a simple name (§6.2) 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 its fully qualified name (§6.7).

A single-type-import declaration (§7.5.1) imports a single type, by mentioning its fully qualified name. A type-import-on-demand declaration (§7.5.2) imports all the public types of a named package as needed.

An import declaration makes types available by their simple names only within the compilation unit that actually contains the import declaration. The scope of the name(s) it introduces specifically does not include the package statement, other import statements in the current compilation unit, or other compilation units in the same package. Please see §7.5.4 for an illustrative example.

7.5.1 Single-Type-Import Declaration

A single-type-import declaration imports a single type by giving its fully qualified name, making it available under a simple name in the class and interface declarations of its compilation unit.

The TypeName must be the fully qualified name of a class or interface type; a compile-time error occurs if the named type does not exist. If the named type is not in the current package, then it must be accessible (§6.6)-in an accessible package and declared public (§8.1.2, §9.1.2)-or a compile-time error occurs.

The example:

import java.util.Vector;
causes the simple name Vector to be available within the class and interface declarations in a compilation unit. Thus, the simple name Vector refers to the type Vector in the package java.util in all places where it is not hidden (§6.3) by a declaration of a field, parameter, or local variable with the same name.

If two single-type-import declarations in the same compilation unit attempt to import types with the same simple name, then a compile-time error occurs, unless the two types are the same type, in which case the duplicate declaration is ignored. If another type with the same name is otherwise declared in the current compilation unit except by a type-import-on-demand declaration (§7.5.2), then a compile-time error occurs.

So the sample program:


import java.util.Vector;
class Vector { Object[] vec; }
causes a compile-time error because of the duplicate declaration of Vector, as does:


import java.util.Vector;
import myVector.Vector;
where myVector is a package containing the compilation unit:


package myVector;
public class Vector { Object[] vec; }
The compiler keeps track of types by their fully qualified names (§6.7). Simple names and fully qualified names may be used interchangeably whenever they are both available.

Note that an import statement cannot import a subpackage, only a type. For example, it does not work to try to import java.util and then use the name util.Random to refer to the type java.util.Random:


import java.util; // incorrect: compile-time error
class Test { util.Random generator; }

7.5.2 Type-Import-on-Demand Declaration

A type-import-on-demand declaration allows all public types declared in the package named by a fully qualified name to be imported as needed.

It is a compile-time error for a type-import-on-demand declaration to name a package that is not accessible (§6.6), as determined by the host system (§7.2). Two or more type-import-on-demand declarations in the same compilation unit may name the same package; the effect is as if there were exactly one such declaration. It is not a compile-time error to name the current package or java.lang in a type-import-on-demand declaration, even though they are already imported; the duplicate type-import-on-demand declaration is ignored.

The example:

import java.util.*;
causes the simple names of all public types declared in the package java.util to be available within the class and interface declarations of the compilation unit. Thus, the simple name Vector refers to the type Vector in the package java.util in all places where it is not hidden (§6.3) by a single-type-import declaration of a type whose simple name is Vector; by a type named Vector and declared in the package to which the compilation unit belongs; or by a declaration of a field, parameter, or local variable named Vector. (It would be unusual for any of these conditions to occur.)

7.5.3 Automatic Imports

Each compilation unit automatically imports each of the public type names declared in the predefined package java.lang, as if the declaration:

import java.lang.*;
appeared at the beginning of each compilation unit, immediately following any package statement.

The full specification of java.lang is given in Chapter 20. The following public types are defined in java.lang:


AbstractMethodError										LinkageError
ArithmeticException										Long
ArrayStoreException										Math
Boolean										NegativeArraySizeException
Character										NoClassDefFoundError
Class										NoSuchFieldError
ClassCastException										NoSuchMethodError
ClassCircularityError										NullPointerException
ClassFormatError										Number
ClassLoader										NumberFormatException
ClassNotFoundException										Object
CloneNotSupportedException										OutOfMemoryError
Cloneable										Process
Compiler										Runnable
Double										Runtime
Error										RuntimeException
Exception										SecurityException
ExceptionInInitializerError										SecurityManager
Float										StackOverflowError
IllegalAccessError										String
IllegalAccessException										StringBuffer
IllegalArgumentException										System
IllegalMonitorStateException										Thread
IllegalThreadStateException										ThreadDeath
IncompatibleClassChangeError										ThreadGroup
IndexOutOfBoundsException										Throwable
InstantiationError										UnknownError
InstantiationException										UnsatisfiedLinkError
Integer										VerifyError
InternalError										VirtualMachineError
InterruptedException

7.5.4 A Strange Example

Package names and type names are usually different under the naming conventions described in §6.8. Nevertheless, in a contrived example where there is an unconventionally-named package Vector, which declares a public class named Mosquito:


package Vector;
public class Mosquito { int capacity; }
and then the compilation unit:


package strange.example;

import java.util.Vector;

import Vector.Mosquito;

class Test {
	public static void main(String[] args) {
		System.out.println(new Vector().getClass());
		System.out.println(new Mosquito().getClass());
	}
}
the single-type-import declaration (§7.5.1) importing class Vector from package java.util does not prevent the package name Vector from appearing and being correctly recognized in subsequent import declarations. The example compiles and produces the output:


class java.util.Vector
class Vector.Mosquito

7.6 Type Declarations

A type declaration declares a class type (§8) or an interface type (§9):

A Java compiler must ignore extra ";" tokens appearing at the level of type declarations. Stray semicolons are permitted in Java solely as a concession to C++ programmers who are used to writing:

class date { int month, day, year; };
(In C++, but not in Java, one can provide a comma-separated list of identifiers in order to declare variables between the "}" and the ";".) Extra semicolons should not be used in new Java code. Software that reformats Java code can delete them.

By default, the types declared in a package are accessible only within the compilation units of that package, but a type may be declared to be public to grant access to the type from code in other packages (§6.6, §8.1.2, §9.1.2).

A Java implementation must keep track of types within packages by their fully qualified names (§6.7). Multiple ways of naming a type must be expanded to fully qualified names to make sure that such names are understood as referring to the same type. For example, if a compilation unit contains the single-type-import declaration (§7.5.1):

import java.util.Vector;
then within that compilation unit the simple name Vector and the fully qualified name java.util.Vector refer to the same type.

When Java packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a Java compiler and Java Virtual Machine to find a named class within a package; for example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket, and the corresponding object code would be found in the file Toad.class in the same directory.

When Java packages are stored in a database (§7.2.2), the host system need not enforce such restrictions.

In practice, many Java programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.

7.7 Unique Package Names

Developers should take steps to avoid the possibility of two published packages having the same name by choosing unique package names for packages that are widely distributed. This allows packages to be easily and automatically installed and catalogued. This section specifies a standard convention, not enforced by a Java compiler, for generating such unique package names. Java systems are encouraged to provide automatic support for converting a set of packages from local and casual package names to the unique name format described here.

If unique package names are not used, then package name conflicts may arise far from the point of creation of either of the conflicting packages. This may create a situation that is difficult or impossible for the user or programmer to resolve. The class ClassLoader (§20.14) of the standard Java Virtual Machine environment can be used to isolate packages with the same name from each other in those cases where the packages will have constrained interactions, but not in a way that is transparent to a naïve Java program.

You form a unique package name by first having (or belonging to an organization that has) an Internet domain name, such as Sun.COM. You then reverse this name, component by component, to obtain, in this example, COM.Sun, and use this as a prefix for your package names, using a convention developed within your organization to further administer package names.

Such a convention might specify that certain directory name components be division, department, project, machine, or login names. Some possible examples:


COM.Sun.sunsoft.DOE
COM.Sun.java.jag.scrabble
COM.Apple.quicktime.v2
EDU.cmu.cs.bovik.cheese
GOV.whitehouse.socks.mousefinder
The first component of a unique package name is always written in all-uppercase ASCII letters and should be one of the top-level domain names, currently COM, EDU, GOV, MIL, NET, ORG, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166, 1981. For more information, refer to the documents stored at ftp://rs.internic.net/rfc, for example, rfc920.txt and rfc1032.txt.

The name of a package is not meant to imply anything about where the package is stored within the Internet; for example, a package named EDU.cmu.cs.bovik.cheese is not necessarily obtainable from Internet address cmu.EDU or from cs.cmu.EDU or from bovik.cs.cmu.EDU. The Java convention for generating unique package names is merely a way to piggyback a package naming convention on top of an existing, widely known unique name registry instead of having to create a separate registry for Java package names.

If you need to get a new Internet domain name, you can get an application form from ftp://ftp.internic.net and submit the complete forms by E-mail to domreg@internic.net. To find out what the currently registered domain names are, you can telnet to rs.internic.net and use the whois facility.


Contents | Prev | Next | Index

Java Language Specification (HTML generated by Suzette Pelouch on February 24, 1998)
Copyright © 1996 Sun Microsystems, Inc. All rights reserved
Please send any comments or corrections to doug.kramer@sun.com



Spec-Zone.ru - all specs in one place



free hit counter