Table of Contents
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 or in a database (§7.2). Packages that are stored in a file system may 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 using qualified names. 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.
The members of a package are its subpackages and all the top level class types (§7.6, §8 (Classes)) and top level interface types (§9 (Interfaces)) declared in all the compilation units (§7.3) of the package.
For example, in the Java SE platform API:
The package java
has
subpackages awt
, applet
,
io
, lang
, net
,
and util
, but no compilation units.
The package java.awt
has a
subpackage named image
, as well as a number
of compilation units containing declarations of class and
interface types.
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, and furthermore denotes a
package.
A package may not contain two members of the same name, or a compile-time error results.
Here are some examples:
Because the package java.awt
has a subpackage image
, it cannot (and does
not) contain a declaration of a class or interface type
named image
.
If there is a package
named 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
.
If com.nighthacks.java.jag
is
the fully qualified name of a type, then there cannot be any
package whose fully qualified name is
either com.nighthacks.java.jag
or com.nighthacks.java.jag.scrabble
.
It is however possible for members of different packages to have the same simple name. For example, it is possible to declare a package:
package vector; public class Vector { Object[] vec; }
that has as a member a public
class
named Vector
, even though the package java.util
also declares a class named Vector
. These two class
types are different, reflected by the fact that they have different
fully qualified names (§6.7). The fully qualified
name of this example Vector
is vector.Vector
,
whereas java.util.Vector
is the fully qualified
name of the Vector
class included in the
Java SE platform. Because the package vector
contains a
class named Vector
, it cannot also have a
subpackage named Vector
.
The hierarchical naming structure for packages is intended to be convenient for organizing related packages in a conventional manner, but has no significance in itself other than the prohibition against a package having a subpackage with the same simple name as a top level type (§7.6) declared in that package.
For example, there is no special access relationship
between a package named oliver
and another package
named oliver.twist
, or between packages
named evelyn.wood
and evelyn.waugh
. That is, 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.
Each host system determines how packages and compilation units are created and stored.
Each host system also determines which compilation units are observable (§7.3) in a particular compilation. The observability of compilation units in turn determines which packages are observable, and which packages are in scope.
In simple implementations of the Java SE platform, packages and compilation units may be stored in a local file system. Other implementations may store them using a distributed file system or some form of database.
If a host system stores packages and compilation units in a database, then the database must not impose the optional restrictions (§7.6) on compilation units permissible 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.
As an extremely simple example of storing packages in a file system, all the packages and source and binary code in a project 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. Each further level of subdirectory would represent a subpackage of the package represented by the containing directory, and so on.
The directory might contain the following immediate subdirectories:
com gls jag java wnj
where directory java
would
contain the Java SE platform 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
§6.1 to generate unique names for their
packages.
Continuing the example, the
directory java
would contain, among others, the
following subdirectories:
applet awt io lang net util
corresponding to the
packages java.applet
, java.awt
,
java.io
, java.lang
,
java.net
, and java.util
that are defined as part
of the Java SE platform API.
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 ...
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 the Java SE 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 an operating system where the file name separator
is /
, the package name:
jag.scrabble.board
would be transformed into the directory name:
jag/scrabble/board
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).
Under this convention, 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 identifier could be used
instead.
CompilationUnit is the goal symbol (§2.1) for the syntactic grammar (§2.3) of Java programs. It is defined by the following productions:
A compilation unit consists of three parts, each of which is optional:
A 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
and static
members of types to be referred to using their simple
names.
Top level type declarations (§7.6) of class and interface types.
Every
compilation unit implicitly imports every public
type name declared
in the predefined package java.lang
, as if the
declaration import java.lang.*;
appeared at the
beginning of each compilation unit immediately after any package
statement. As a result, the names of all those types are available as
simple names in every compilation unit.
All the compilation units of
the predefined package java
and
its subpackages lang
and io
are always
observable.
For all other packages, the host system determines which compilation units are observable.
The observability of a compilation unit influences the observability of its package (§7.4.3).
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 package
declaration appears
within a compilation unit to indicate the package to which the
compilation unit belongs.
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 of the package (§6.7).
The scope and shadowing of a package declaration is specified in §6.3 and §6.4.
The rules for annotation modifiers on a package declaration are specified in §9.7.4 and §9.7.5.
At most
one annotated package
declaration is permitted for a given
package.
The manner in which this restriction is enforced
must, of necessity, vary from implementation to implementation. The
following scheme is strongly recommended for file-system-based
implementations: The sole annotated package
declaration, if it
exists, is placed in a source file
called package-info.java
in the directory
containing the source files for the package. This file does not
contain the source for a class called
package-info.java
; indeed it would be illegal for
it to do so, as package-info
is not a legal
identifier. Typically package-info.java
contains
only a package
declaration, preceded immediately by the annotations
on the package. While the file could technically contain the source
code for one or more classes with package access, it would be very bad
form.
It is recommended
that package-info.java
, if it is present, take the
place of package.html
for javadoc
and other similar documentation
generation systems. If this file is present, the documentation
generation tool should look for the package documentation comment
immediately preceding the (possibly annotated) package
declaration
in package-info.java
. In this
way, package-info.java
becomes the sole repository
for package-level annotations and documentation. If, in future, it
becomes desirable to add any other package-level information, this
file should prove a convenient home for this information.
A
compilation unit that has no package
declaration is part of
an unnamed package.
Unnamed packages are provided by the Java SE platform principally for convenience when developing small or temporary applications or when just beginning development.
An unnamed package cannot
have subpackages, since the syntax of a package
declaration always
includes a reference to a named top level package.
An implementation of the Java SE platform must support at least one unnamed package. An implementation 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.
Example 7.4.2-1.
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.
In implementations of the Java SE 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.
A package is observable if and only if either:
A compilation unit containing a declaration of the package is observable (§7.3).
The
packages java
, java.lang
, and java.io
are always
observable.
One can conclude this from the rule above and from
the rules of observable compilation units, as follows. The predefined
package java.lang
declares the class Object
, so the compilation
unit for Object
is always observable
(§7.3). Hence, the java.lang
package is
observable (§7.4.3), and
the java
package also. Furthermore, since Object
is observable, the array type Object
[]
implicitly
exists. Its superinterface java.io.Serializable
(§10.1)
also exists, hence the java.io
package is observable.
An import declaration allows
a named type or a static
member 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, or a static
member of another type, is
to use a fully qualified name (§6.7).
A single-type-import declaration (§7.5.1) imports a single named type, by mentioning its canonical name (§6.7).
A type-import-on-demand declaration (§7.5.2) imports all the accessible types (§6.6) of a named type or named package as needed, by mentioning the canonical name of a type or package.
A single-static-import
declaration (§7.5.3) imports all accessible
static
members with a given name from a type, by giving its
canonical name.
A static-import-on-demand
declaration (§7.5.4) imports all accessible
static
members of a named type as needed, by mentioning the
canonical name of a type.
The scope and shadowing of a type or member imported by these declarations is specified in §6.3 and §6.4.
An import
declaration makes types or members
available by their simple names only within the compilation unit that
actually contains the import
declaration. The scope of the type(s)
or member(s) introduced by an import
declaration specifically does
not include other compilation units in the same package, other
import
declarations in the current compilation unit, or a package
declaration in the current compilation unit (except for the
annotations of a package
declaration).
A single-type-import declaration imports a single type by giving its canonical name, making it available under a simple name in the class and interface declarations of the compilation unit in which the single-type-import declaration appears.
The TypeName must be the canonical name of a class type, interface type, enum type, or annotation type (§6.7).
The name must be qualified (§6.5.5.2), or a compile-time error occurs.
It is a compile-time error if the named type is not accessible (§6.6).
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 the
type imported by the single-type-import declaration is declared in the
compilation unit that contains the import
declaration, the import
declaration is ignored.
If a single-type-import declaration imports a type whose simple name is n, and the compilation unit also declares a top level type (§7.6) whose simple name is n, a compile-time error occurs.
If a compilation unit contains both a single-type-import declaration that imports a type whose simple name is n, and a single-static-import declaration (§7.5.3) that imports a type whose simple name is n, a compile-time error occurs.
Example 7.5.1-1. Single-Type-Import
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 declaration Vector
in the
package java.util
in all places where it is not shadowed
(§6.4.1) or obscured
(§6.4.2) by a declaration of a field, parameter,
local variable, or nested type declaration with the same name.
Note that the actual declaration
of java.util.Vector
is generic
(§8.1.2). Once imported, the
name Vector
can be used without qualification in a
parameterized type such as Vector<String>
, or
as the raw type Vector
. A related limitation of the
import
declaration is that a nested type declared inside a generic
type declaration can be imported, but its outer type is always
erased.
Example 7.5.1-2. Duplicate Type Declarations
This 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; }
Example 7.5.1-3. No Import of a Subpackage
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; class Test { util.Random generator; } // incorrect: compile-time error
Example 7.5.1-4. Importing a Type Name that is also a Package Name
Package names and type names are usually different
under the naming conventions described in
§6.1. Nevertheless, in a contrived example where
there is an unconventionally-named package Vector
,
which declares a public class whose name
is Mosquito
:
package Vector; public class Mosquito { int capacity; }
and then the compilation unit:
package strange; 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 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
A type-import-on-demand declaration allows all accessible types of a named package or type to be imported as needed.
The PackageOrTypeName must be the canonical name (§6.7) of a package, a class type, an interface type, an enum type, or an annotation type.
If the PackageOrTypeName denotes a type (§6.5.4), then the name must be qualified (§6.5.5.2), or a compile-time error occurs.
It is a compile-time error if the named package or type is not accessible (§6.6).
It is not
a compile-time error to name either java.lang
or the named package of
the current compilation unit in a type-import-on-demand
declaration. The type-import-on-demand declaration is ignored in such
cases.
Two or more type-import-on-demand declarations in the same compilation unit may name the same type or package. All but one of these declarations are considered redundant; the effect is as if that type was imported only once.
If a
compilation unit contains both a type-import-on-demand declaration and
a static-import-on-demand declaration (§7.5.4)
that name the same type, the effect is as if the static
member types
of that type (§8.5, §9.5)
were imported only once.
Example 7.5.2-1. Type-Import-on-Demand
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
in the compilation unit where that type declaration is not shadowed
(§6.4.1) or obscured
(§6.4.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.)
A single-static-import
declaration imports all accessible static
members with a
given simple name from a type. This makes these static
members
available under their simple name in the class and interface
declarations of the compilation unit in which the single-static-import
declaration appears.
The TypeName must be the canonical name (§6.7) of a class type, interface type, enum type, or annotation type.
The name must be qualified (§6.5.5.2), or a compile-time error occurs.
It is a compile-time error if the named type is not accessible (§6.6).
The
Identifier must name at least one static
member of the named
type. It is a compile-time error if there is
no static
member of that name, or if all of the
named members are not accessible.
It is permissible for one single-static-import declaration to import several fields or types with the same name, or several methods with the same name and signature.
If a single-static-import declaration imports a type whose simple name is n, and the compilation unit also declares a top level type (§7.6) whose simple name is n, a compile-time error occurs.
If a compilation unit contains both a single-static-import declaration that imports a type whose simple name is n, and a single-type-import declaration (§7.5.1) that imports a type whose simple name is n, a compile-time error occurs.
A static-import-on-demand
declaration allows all accessible static
members of a named type to be imported as
needed.
The TypeName must be the canonical name (§6.7) of a class type, interface type, enum type, or annotation type.
The name must be qualified (§6.5.5.2), or a compile-time error occurs.
It is a compile-time error if the named type is not accessible (§6.6).
Two or more static-import-on-demand declarations in the same compilation unit may name the same type; the effect is as if there was exactly one such declaration.
Two or more static-import-on-demand declarations in the same compilation unit may name the same member; the effect is as if the member was imported exactly once.
It is permissible for one static-import-on-demand declaration to import several fields or types with the same name, or several methods with the same name and signature.
If a
compilation unit contains both a static-import-on-demand declaration
and a type-import-on-demand declaration (§7.5.2)
that name the same type, the effect is as if the static
member types
of that type (§8.5, §9.5)
were imported only once.
A top level type declaration declares a top level class type (§8 (Classes)) or a top level interface type (§9 (Interfaces)).
Extra ";
" tokens appearing at the level of type
declarations in a compilation unit have no effect on the meaning of
the compilation unit. Stray semicolons are permitted in the Java programming language
solely as a concession to C++ programmers who are used to placing
";
" after a class declaration. They should not be used in new
Java code.
In the absence of an access modifier, a
top level type has package access: it is accessible only within
compilation units of the package in which it is declared
(§6.6.1). A type may be declared public
to
grant access to the type from code in other packages.
It is a
compile-time error if a top level type declaration contains any one of
the following access modifiers: protected
, private
, or
static
.
It is a compile-time error 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.
The scope and shadowing of a top level type is specified in §6.3 and §6.4.
The fully qualified name of a top level type is specified in §6.7.
Example 7.6-1. Conflicting Top Level Type Declarations
package 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
Here, the first compile-time error is caused by the
duplicate declaration of the name Point
as both a
class and an interface in the same package. A second compile-time
error 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 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. Thus, in this program:
package test; import java.util.*; class Vector {} // not a compile-time error
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).
Example 7.6-2. Scope of Top Level Types
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 }
This program 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 program compiles correctly. That is, forward reference is not a
problem.
Example 7.6-3. Fully Qualified Names
class Point { int x, y; }
In this code, the class Point
is
declared in a compilation unit with no package
statement, and
thus Point
is its fully qualified name, whereas in
the code:
package vista; class Point { int x, y; }
the fully qualified name of the
class Point
is 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
(§6.1).)
An implementation of the Java SE 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):
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.
If and only
if packages are stored in a file system (§7.2),
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 to find a
named class within a package. 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.
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.