Contents | Prev | Next | Index | Java Language Specification Second Edition |
CHAPTER 7
Programs are organized as sets of packages. Each package has its own set of names for types, which helps to prevent name conflicts. A top level 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.
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 all of the public types declared in the predefined package java.lang
.
For small programs and casual development, a package can be unnamed (§7.4.2) or have a simple name, but if 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.
For example, in the Java Application Programming Interface:
java
has subpackages awt
, applet
, io
, lang
, net
, and util
, but no compilation units.
java.awt
has a subpackage named image
, as well as a number of compilation units containing declarations of class and interface types.
.
Q is the fully qualified name of the subpackage.A package may not contain two members of the same name, or a compile-time error results.
java.awt
has a subpackage image
, it cannot (and does not) contain a declaration of a class or interface type named image
.
mouse
and a member type Button
in that package (which then might be referred to as mouse.Button
), then there cannot be any package with the fully qualified name mouse.Button
or mouse.Button.Click
.
com.sun.java.jag
is the fully qualified name of a type, then there cannot be any package whose fully qualified name is either com.sun.java.jag
or com.sun.java.jag.scrabble
.
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.
The observability of compilation units in turn determines which packages are observable, and which packages are in scope.
The packages may be stored in a local file system in simple implementations of the Java platform. Other implementations may use a distributed file system or some form of database to store source and/or binary code.
where directorycom gls jag java wnj
java
would contain the Java Application Programming Interface packages; the directories jag
, gls
, and wnj
might contain packages that three of the 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 contain, among others, the following subdirectories:
corresponding to the packagesapplet awt io lang net util
java.applet
, java.awt
, java.io
, java.lang
, java.net
, and java.util
that are defined as part of the Java Application Programming Interface.
Still continuing the example, if we were to look inside the directory util
, we might see the following files:
where each of theBitSet.java Observable.java BitSet.class Observable.class Date.java Observer.java Date.class Observer.class ...
.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 the Java platform 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:
would be transformed into the directory name:jag.scrabble.board
and:jag/scrabble/board
would be transformed to the directory name:com.sun.sunsoft.DOE
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, thecom/sun/sunsoft/DOE
@
character followed by four hexadecimal digits giving the numeric value of the character, as in the \u
xxxx escape (§3.3), so that the package name:
which can also be written using full Unicode as:children.activities.crafts.papierM\u00e2ch\u00e9
might be mapped to the directory name:children.activities.crafts.papierMâché
If thechildren/activities/crafts/papierM@00e2ch@00e9
@
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 an identifier could be used instead.
Such a database must not impose the optional restrictions (§7.6) on compilation units in file-based implementations. For example, a system that uses a database to store packages may 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 program to a form that obeys the restrictions, for purposes of export to file-based implementations.
CompilationUnit: PackageDeclarationoptTypes 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.ImportDeclarationsopt
TypeDeclarationsopt ImportDeclarations: ImportDeclaration ImportDeclarations
ImportDeclaration TypeDeclarations: TypeDeclaration TypeDeclarations
TypeDeclaration
A compilation unit consists of three parts, each of which is optional:
package
declaration (§7.4), giving the fully qualified name (§6.7) of the package to which the compilation unit belongs. A compilation unit that has no package declaration is part of an unnamed package (§7.4.2).
import
declarations (§7.5) that allow types from other packages to be referred to using their simple names
java
and its subpackages lang
and io
must always be observable. The observability of a compilation unit influences the observability of its package (§7.4.3).
Every compilation unit automatically and implicitly imports every public
type name declared by the predefined package java.lang
, so that the names of all those types are available as simple names, as described in §7.5.3.
PackageDeclaration:The package name mentioned in a package declaration must be the fully qualified name (§6.7) of the package.package
PackageName;
Note that an unnamed package cannot have subpackages, since the syntax of a package declaration always includes a reference to a named top level package.
As an example, the compilation unit:
defines a very simple compilation unit as part of an unnamed package.class FirstCall { public static void main(String[] args) { System.out.println("Mr. Watson, come here. " + "I want you."); } }
An implementation of the Java platform 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 implementations of the Java platform 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 observable 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 the Java platform principally for convenience when developing small or temporary applications or when just beginning development.
java
, java.lang
, and java.io
are always observable.
It follows that the package java
is always in scope (§6.3).
Package declarations never shadow other declarations.
import
declaration, the only way to refer to a type declared in another package is to use a fully qualified name (§6.7).
ImportDeclaration: SingleTypeImportDeclaration TypeImportOnDemandDeclarationA single-type-import declaration (§7.5.1) imports a single named type, by mentioning its canonical name. A type-import-on-demand declaration (§7.5.2) imports all the accessible types of a named type or package as needed.
The scope of a type imported by a single-type-import declaration (§7.5.1) or type-import-on-demand declaration (§7.5.2) is all the class and interface type declarations (§7.6) in the compilation unit in which the import declaration appears.
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 entities(s) it introduces specifically does not include the package
statement, other import
declarations in the current compilation unit, or other compilation units in the same package. See §7.5.4 for an illustrative example.
SingleTypeImportDeclaration:
import
TypeName ;
The TypeName must be the canonical name of a class or interface type; a compile-time error occurs if the named type does not exist. The named type must be accessible (§6.6) or a compile-time error occurs.A single-type-import declaration d in a compilation unit c of package p that imports a type named n shadows the declarations of:
causes the simple nameimport java.util.Vector;
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 shadowed (§6.3.1) or obscured (§6.3.2) by a declaration of a field, parameter, local variable, or nested type declaration 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 top level type with the same simple 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.
causes a compile-time error because of the duplicate declaration ofimport java.util.Vector; class Vector { Object[] vec; }
Vector
, as does:
whereimport java.util.Vector; import myVector.Vector;
myVector
is a package containing the compilation unit:
The compiler keeps track of types by their binary names (§13.1).package myVector; public class Vector { Object[] vec; }
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; }
TypeImportOnDemandDeclaration:It is a compile-time error for a type-import-on-demand declaration to name a type or package that is not accessible. Two or more type-import-on-demand declarations in the same compilation unit may name the same type or package; the effect is as if there were exactly one such declaration. It is not a compile-time error to name the current package orimport
PackageOrTypeName. * ;
java.lang
in a type-import-on-demand declaration. The type-import-on-demand declaration is ignored in such casesA type-import-on-demand declaration never causes any other declaration to be shadowed.
causes the simple names of allimport java.util.*;
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 in the compilation unit where that type declaration is not shadowed (§6.3.1) or obscured (§6.3.2). The declaration might be shadowed 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 any nested classes or interfaces. The declaration might be obscured by a declaration of a field, parameter, or local variable named Vector
(It would be unusual for any of these conditions to occur.)public
type names declared in the predefined package java.lang
, as if the declaration:
appeared at the beginning of each compilation unit, immediately following anyimport java.lang.*;
package
statement.Vector
, which declares a public
class named Mosquito
:
and then the compilation unit:package Vector; public class Mosquito { int capacity; }
the single-type-import declaration (§7.5.1) importing classpackage 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()); } }
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
TypeDeclaration:
ClassDeclaration
InterfaceDeclaration
;
By default, the top level 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.1, §9.1.1).The scope of a top level type is all type declarations in the package in which the top level type is declared.
If a top level 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. If the type is declared in an unnamed package (§7.4.2), then the type has the fully qualified name T.
the fully qualified name of classpackage wnj.points; class Point { int x, y; }
Point
is wnj.points.Point
. An implementation of the Java platform must keep track of types within packages by their binary names (§13.1). Multiple ways of naming a type must be expanded to binary 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):
then within that compilation unit the simple nameimport java.util.Vector;
Vector
and the fully qualified name java.util.Vector
refer to the same type.
When 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:
public
(and therefore is potentially accessible from code in other packages).
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 packages are stored in a database (§7.2.2), the host system must not impose such restrictions.
In practice, many 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.
A compile-time error occurs if the name of a top level type appears as the name of any other top level class or interface type declared in the same package (§7.6).
A compile-time error occurs if the name of a top level type is also declared as a type by a single-type-import declaration (§7.5.1) in the compilation unit (§7.3) containing the type declaration.
the class Point is declared in a compilation unit with no package statement, and thus Point is its fully qualified name, whereas in the example:class Point { int x, y; }
the fully qualified name of the class Point ispackage vista; class Point { int x, y; }
vista.Point
. (The package name vista is suitable for local or personal use; if the package were intended to be widely distributed, it would be better to give it a unique package name (§7.7).)the first compile-time error is caused by the duplicate declaration of the name Point as both a class and anpackage test; import java.util.Vector; class Point { int x, y; } interface Point { // compile-time error #1 int getR(); int getTheta(); } class Vector { Point[] pts; } // compile-time error #2
interface
in the same package. A second error detected at compile time is the attempt to declare the name Vector both by a class type declaration and by a single-type-import declaration.Note, however, that it is not an error for the name of a class to also to name a type that otherwise might be imported by a type-import-on-demand declaration (§7.5.2) in the compilation unit (§7.3) containing the class declaration. In the example:
the declaration of the class Vector is permitted even though there is also a class java.util.Vector. Within this compilation unit, the simple name Vector refers to the class test.Vector, not to java.util.Vector (which can still be referred to by code within the compilation unit, but only by its fully qualified name).package test; import java.util.*; class Vector { Point[] pts; } // not a compile-time error
As another example, the compilation unit:
defines two classes that use each other in the declarations of their class members. Because the class types Point and PointColor have all the type declarations in package points, including all those in the current compilation unit, as their scope, this example compiles correctly-that is, forward reference is not a problem.package points; class Point { int x, y; // coordinates PointColor color; // color of this point Point next; // next point with this color static int nPoints; } class PointColor { Point first; // first point with this color PointColor(int color) { this.color = color; } private int color; // color components }
It is a compile-time error if a top level type declaration contains any one of the following access modifiers: protected, private or static.
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
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 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.
In some cases, the internet domain name may not be a valid package name. Here are some suggested conventions for dealing with these situations:
The first component of a unique package name is always written in all-lowercase ASCII letters and should be one of the top level domain names, currentlycom.sun.sunsoft.DOE com.sun.java.jag.scrabble com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese gov.whitehouse.socks.mousefinder
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 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 suggested 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 package names.
Contents | Prev | Next | Index | Java Language Specification Second Edition |