A declared entity
(§6.1) is a package, class type (normal or enum),
interface type (normal or annotation type), member (class, interface,
field, or method) of a reference type, type parameter (of a class,
interface, method or constructor), parameter (to a method,
constructor, or exception handler), or local variable.

Names in programs are
either simple, consisting of a single identifier,
or qualified, consisting of a sequence of
identifiers separated by "." tokens
(§6.2).

Every declaration that introduces
a name has a scope (§6.3),
which is the part of the program text within which the declared entity
can be referred to by a simple name.

A qualified
name N.x may be used to refer to
a member of a package or reference
type, where N is a simple
or qualified name and x is an
identifier. If N names a package,
then x is a member of that package, which is either
a class or interface type or a subpackage. If N
names a reference type or a variable of a reference type,
then x names a member of that type, which is either
a class, an interface, a field, or a method.

In determining the meaning of a
name (§6.5), the context of the occurrence is
used to disambiguate among packages, types, variables, and methods
with the same name.

Access control
(§6.6) can be specified in a class, interface,
method, or field declaration to control
when access to a member is allowed. Access is a
different concept from scope. Access specifies the part of the program
text within which the declared entity can be referred to by a
qualified name, a field access expression
(§15.11), or a method invocation expression
(§15.12) in which the method is not specified by
a simple name. The default access is that a member can be accessed
anywhere within the package that contains its declaration; other
possibilities are public, protected, and private.

Fully qualified and canonical
names (§6.7) are also discussed in this
chapter.

6.1. Declarations

A
declaration introduces an
entity into a program and includes an identifier
(§3.8) that can be used in a name to refer to
this entity.

Constructors
(§8.8) are also introduced by declarations, but
use the name of the class in which they are declared rather than
introducing a new name.

The class libraries of the Java SE platform attempt to
use, whenever possible, names chosen according to the conventions
presented below. These conventions help to make code more readable and
avoid certain kinds of name conflicts.

We recommend these conventions for use in all
programs written in the Java programming language. However, these
conventions should not be followed slavishly if long-held conventional
usage dictates otherwise. So, for example, the sin
and cos methods of the
class java.lang.Math have mathematically
conventional names, even though these method names flout the
convention suggested here because they are short and are not
verbs.

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
suggested convention for generating such unique package
names. Implementations of the Java SE platform 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 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 oracle.com. You then reverse this name,
component by component, to obtain, in this
example, com.oracle, 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 package name components be
division, department, project, machine, or login names.

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, such as com,
edu, gov, mil,
net, or org, or one of the
English two-letter codes identifying countries as specified
in ISO Standard 3166.

The name of a package is not meant to imply where
the package is stored on the Internet. 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.

For example, a package
named edu.cmu.cs.bovik.cheese is not necessarily
obtainable from Internet address cmu.edu
or cs.cmu.edu
or bovik.cs.cmu.edu.

In some cases, the Internet domain name may not be a
valid package name. Here are some suggested conventions for dealing
with these situations:

If the domain name contains a hyphen, or any
other special character not allowed in an identifier
(§3.8), convert it into an
underscore.

If any of the resulting package name components
are keywords (§3.9), append an underscore
to them.

If any of the resulting package name components
start with a digit, or any other character that is not allowed
as an initial character of an identifier, have an underscore
prefixed to the component.

Names of packages intended only for local use should
have a first identifier that begins with a lowercase letter, but that
first identifier specifically should not be the
identifier java; package names that start with the
identifier java are reserved for package of the
Java SE platform.

Class and Interface Type
Names

Names of class types should be descriptive nouns or
noun phrases, not overly long, in mixed case with the first letter of
each word capitalized.

Example 6.1-2. Descriptive Class Names

ClassLoader
SecurityManager
Thread
Dictionary
BufferedInputStream

Likewise, names of interface types should be short
and descriptive, not overly long, in mixed case with the first letter
of each word capitalized. The name may be a descriptive noun or noun
phrase, which is appropriate when an interface is used as if it were
an abstract superclass, such as interfaces
java.io.DataInput and
java.io.DataOutput; or it may be an adjective
describing a behavior, as for the interfaces
Runnable and Cloneable.

Type Variable Names

Type variable names should be pithy (single
character if possible) yet evocative, and should not include lower
case letters. This makes it easy to distinguish type parameters from
ordinary classes and interfaces.

Container types should use the
name E for their element type. Maps should
use K for the type of their keys
and V for the type of their values. The
name X should be used for arbitrary exception
types. We use T for type, whenever there is not
anything more specific about the type to distinguish it. (This is
often the case in generic methods.)

If there are multiple type parameters that denote
arbitrary types, one should use letters that
neighbor T in the alphabet, such
as S. Alternately, it is acceptable to use numeric
subscripts (e.g., T1, T2) to
distinguish among the different type variables. In such cases, all the
variables with the same prefix should be subscripted.

If a generic method appears inside a generic class,
it is a good idea to avoid using the same names for the type
parameters of the method and class, to avoid confusion. The same
applies to nested generic classes.

When type parameters do not fall conveniently into
one of the categories mentioned, names should be chosen to be as
meaningful as possible within the confines of a single letter. The
names mentioned above (E, K,
V, X, T)
should not be used for type parameters that do not fall into the
designated categories.

Method Names

Method names should be verbs or verb phrases, in
mixed case, with the first letter lowercase and the first letter of
any subsequent words capitalized. Here are some additional specific
conventions for method names:

Methods to get and set an attribute that might
be thought of as a variable V should be
named getV
and setV. An example is
the methods getPriority
and setPriority of class Thread.

A method that returns the length of something
should be named length, as in class
String.

A method that tests a boolean
condition V about an object should be
named isV. An example is
the method isInterrupted of class
Thread.

A method that converts its object to a
particular format F should be
named toF. Examples are
the method toString of class Object and the
methods toLocaleString
and toGMTString of
class java.util.Date.

Whenever possible and appropriate, basing the names
of methods in a new class on names in an existing class that is
similar, especially a class from the Java SE platform API, will make it
easier to use.

Field Names

Names of fields that are not final should be in
mixed case with a lowercase first letter and the first letters of
subsequent words capitalized. Note that well-designed classes have
very few public or protected fields, except for fields that are
constants (staticfinal fields).

Fields should have names that are nouns, noun
phrases, or abbreviations for nouns.

Examples of this convention are the
fields buf, pos,
and count of the
class java.io.ByteArrayInputStream and the
field bytesTransferred of the
class java.io.InterruptedIOException.

Constant Names

The names of constants in interface types should be,
and final variables of class types may conventionally be, a sequence
of one or more words, acronyms, or abbreviations, all uppercase, with
components separated by underscore "_"
characters. Constant names should be descriptive and not unnecessarily
abbreviated. Conventionally they may be any appropriate part of
speech.

Examples of names for constants
include MIN_VALUE, MAX_VALUE,
MIN_RADIX, and MAX_RADIX of the
class Character.

A group of constants that represent alternative
values of a set, or, less frequently, masking bits in an integer
value, are sometimes usefully specified with a common acronym as a
name prefix.

For example:

interface ProcessStates {
int PS_RUNNING = 0;
int PS_SUSPENDED = 1;
}

Local Variable and Parameter
Names

Local variable and parameter names should be short,
yet meaningful. They are often short sequences of lowercase letters
that are not words, such as:

Acronyms, that is the first letter of a series
of words, as in cp for a variable holding a
reference to a ColoredPoint

Abbreviations, as in buf
holding a pointer to a buffer of some kind

Mnemonic terms, organized in some way to aid
memory and understanding, typically by using a set of local
variables with conventional names patterned after the names of
parameters to widely used classes. For example:

in
and out, whenever some kind of input and
output are involved, patterned after the fields
of System

off
and len, whenever an offset and length
are involved, patterned after the parameters to
the read and write
methods of the interfaces DataInput
and DataOutput
of java.io

One-character local variable or parameter names
should be avoided, except for temporary and looping variables, or
where a variable holds an undistinguished value of a
type. Conventional one-character names are:

b for a byte

c for a char

d for a double

e for an Exception

f for a float

i, j,
and k for ints

l for a long

o for an Object

s for a String

v for an arbitrary value of
some type

Local variable or parameter names that consist of
only two or three lowercase letters should not conflict with the
initial country codes and domain names that are the first component of
unique package names.

6.2. Names and Identifiers

A name is
used to refer to an entity declared in a program.

There are two forms of names:
simple names and qualified names.

A simple
name is a single identifier.

A qualified
name consists of a name, a "." token, and an
identifier.

In determining the meaning of a
name (§6.5), the context in which the name
appears is taken into account. The rules of §6.5
distinguish among contexts where a name must denote (refer to) a
package (§6.5.3), a type
(§6.5.5), a variable or value in an expression
(§6.5.6), or a method
(§6.5.7).

Packages and reference types
have members which may be accessed by qualified
names. As background for the discussion of qualified names and the
determination of the meaning of names, see the descriptions of
membership in §4.4, §4.5.2,
§4.8, §4.9,
§7.1, §8.2,
§9.2, and §10.7.

Not all identifiers in a
program are a part of a name. Identifiers are also used in the
following situations:

In declarations
(§6.1), where an identifier may occur to
specify the name by which the declared entity will be
known.

As labels in labeled
statements (§14.7) and in break and
continue statements (§14.15,
§14.16) that refer to statement
labels.

In field access
expressions (§15.11), where an identifier
occurs after a "." token to indicate a member of an object
that is the value of an expression or the keyword super that
appears before the "." token

In some method invocation
expressions (§15.12), where an identifier
may occur after a "." token and before a "(" token to
indicate a method to be invoked for an object that is the value
of an expression or the keyword super that appears before the
"." token

In qualified class
instance creation expressions (§15.9),
where an identifier occurs immediately to the right of the
leftmost new token to indicate a type that must be a member of
the compile-time type of the primary expression preceding the
"." preceding the leftmost new token.

the
identifiers Test, main, and the
first occurrences of args and c
are not names. Rather, they are used in declarations to specify the
names of the declared entities. The names String,
Class, System.out.getClass,
System.out.println, c.toString,
args, and args.length appear in
the example. The occurrence of length
in args[0].length() is not a name, but rather an
identifier appearing in a method invocation expression
(§15.12). The occurrence
of length in args.length is a
name because args.length is a qualified name
(§6.5.6.2) and not a field access expression
(§15.11). (A field access expression, like a
method invocation expression, uses an identifier rather than a name to
denote the member of interest.)

One might wonder
why these kinds of expression use an identifier rather than a simple
name, which is after all just an identifier. The reason is that a
simple expression name is defined in terms of the lexical environment;
that is, a simple expression name must be in the scope of a variable
declaration. But field access, and method invocation qualified by
a Primary, and qualified class instance creation
all denote members whose names are not in the lexical environment. By
definition, such names are bound only in the context provided by
the Primary of the field access expression,
method invocation expression, or class instance creation
expression. Therefore, we denote such members with identifiers rather
than simple names.

To complicate
things further, a field access expression is not the only way to
denote a field of an object. For parsing reasons, a qualified name is
used to denote a field of an in-scope variable. (The variable itself
is denoted with a simple name, alluded to above.) It is necessary for
access control (§6.6) to capture both mechanisms
for denoting a field.

The identifiers used in labeled
statements (§14.7) and their associated break
and continue statements (§14.15,
§14.16) are completely separate from those used
in declarations.

Example 6.2-1. Identifiers and Obscuring

The following code was taken from a version of the
class String and its method indexOf, where the
label was originally called test. Changing the
label to have the same name as the local variable i
does not obscure (§6.4.2) the label in the scope
of the declaration of i. Thus, the code is
valid.

The identifier max could also
have been used as the statement label; the label would not obscure the
local variable max within the labeled
statement.

6.3. Scope of a Declaration

The scope
of a declaration is the region of the program within which the entity
declared by the declaration can be referred to using a simple name,
provided it is visible (§6.4.1).

A declaration is said to
be in scope at a particular point in a program if
and only if the declaration's scope includes that point.

The scope of
the declaration of an observable (§7.4.3) top
level package is all observable compilation units
(§7.3).

The
declaration of a package that is not observable is never in
scope.

The
declaration of a subpackage is never in scope.

The
package java is always in scope.

The scope of
a type imported by a single-type-import declaration
(§7.5.1) or a 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, as well as any
annotations on the package declaration (if any) of the compilation
unit .

The scope of
a member imported by a single-static-import declaration
(§7.5.3) or a static-import-on-demand declaration
(§7.5.4) is all the class and interface type
declarations (§7.6) in the compilation unit in
which the import declaration appears, as well as any
annotations on the package declaration (if any) of the compilation
unit .

The scope of
a top level type (§7.6) is all type declarations
in the package in which the top level type is declared.

The scope of
a declaration of a member m declared in or
inherited by a class type C (§8.1.6) is the
entire body of C, including any nested type declarations.

The scope of
a declaration of a member m declared in or
inherited by an interface type I (§9.1.4) is
the entire body of I, including any nested type declarations.

The scope of
an enum constant C declared in an enum type T is the body of T,
and any case label of a switch statement whose expression is of
enum type T.

The scope of
a formal parameter of a method (§8.4.1) or
constructor (§8.8.1) is the entire body of the
method or constructor.

The
scope of a class's type parameter (§8.1.2)
is the type parameter section of
the class declaration, the type parameter section of any superclass or
superinterface of the class declaration, and the class
body.

The
scope of an interface's type parameter (§9.1.2)
is the type parameter section of
the interface declaration, the type parameter section of any
superinterface of the interface declaration, and the interface
body.

The
scope of a method's type parameter (§8.4.4) is
the entire declaration of the method, including the type parameter
section, but excluding the method
modifiers.

The
scope of a constructor's type parameter (§8.8.4)
is the entire declaration of the constructor, including the type
parameter section, but excluding the constructor
modifiers.

The scope of
a local class declaration immediately enclosed by a block
(§14.2) is the rest of the immediately enclosing
block, including its own class declaration.

The scope of a local class declaration
immediately enclosed by a switch block statement group
(§14.11) is the rest of the immediately enclosing
switch block statement group, including its own class
declaration.

The scope of
a local variable declaration in a block (§14.4)
is the rest of the block in which the declaration appears, starting
with its own initializer and including any further declarators to the
right in the local variable declaration statement.

The scope of
a local variable declared in the ForInit part of
a basic for statement (§14.14.1) includes all
of the following:

Its
own initializer

Any
further declarators to the right in
the ForInit part of the for
statement

The Expression
and ForUpdate parts of the for
statement

The
contained Statement

The scope of
a local variable declared in the FormalParameter
part of an enhanced for statement (§14.14.2) is
the contained Statement.

The scope of
a parameter of an exception handler that is declared in a catch
clause of a try statement (§14.20) is the
entire block associated with the catch.

The scope of a
variable declared in the ResourceSpecification of
a try-with-resources statement (§14.20.3) is
from the declaration rightward over the remainder of
the ResourceSpecification and the entire try
block associated with the try-with-resources statement.

The translation of a try-with-resources statement
implies the rule above.

Example 6.3-1. Scope and Type Declarations

These rules imply that declarations of class and
interface types need not appear before uses of the types. In the
following program, the use of PointList in
class Point is valid, because the scope of the
class declaration PointList includes both
class Point and class PointList,
as well as any other type declarations in other compilation units of
package points.

This program causes a compile-time error because the
initialization of x is within the scope of the
declaration of x as a local variable, and the local
variable x does not yet have a value and cannot be
used.

because the local variable x is
definitely assigned (§16) before it is used. It
prints:

4

In the following program, the initializer
for three can correctly refer to the
variable two declared in an earlier declarator, and
the method invocation in the next line can correctly refer to the
variable three declared earlier in the
block.

6.4. Shadowing and Obscuring

A local
variable (§14.4), formal parameter
(§8.4.1), exception parameter
(§14.20), and local class
(§14.3) can only be referred to using a simple
name (§6.2), not a qualified name
(§6.6).

Some declarations are not
permitted within the scope of a local variable, formal parameter,
exception parameter, or local class declaration because it would be
impossible to distinguish between the declared entities using only
simple names.

For example, if the name of a formal parameter of a
method could be redeclared as the name of a local variable in the
method body, then the local variable would shadow the formal parameter
and the formal parameter would no longer be visible - an undesirable
outcome.

It is a
compile-time error if the name of a formal parameter is redeclared as
a local variable of the method or constructor; or
as an exception parameter of a catch clause in a try statement in
the body of the method or constructor; or as a resource in a
try-with-resources statement in the body of the method or
constructor.

It is a
compile-time error if the name of a local
variable v is redeclared as a local variable of the
directly enclosing method, constructor, or initializer block within
the scope of v; or as an exception parameter of a
catch clause in a try statement of the directly enclosing method,
constructor or initializer block within the scope
of v; or as a resource in a
try-with-resources statement of the directly enclosing method,
constructor or initializer block within the scope
of v.

It is a
compile-time error if the name of a local class C is redeclared as a
local class of the directly enclosing method, constructor, or
initializer block within the scope of C.

It is a
compile-time error if the name of an exception parameter is redeclared
within the Block of the catch clause as a local variable of the
directly enclosing method, constructor, or initializer block; or as an
exception parameter of a catch clause in a try statement of the
directly enclosing method, constructor or initializer
block; or as a resource in a try-with-resources statement
of the directly enclosing method, constructor or initializer
block.

It is a
compile-time error if the name of a variable declared in
a ResourceSpecification of a try-with-resources
statement (§14.20.3) is redeclared within the
tryBlock as a local variable of the directly enclosing method,
constructor, or initializer block, or as an exception parameter of a
catch clause in a try statement of the directly enclosing method
or initializer block.

The translation of a try-with-resources statement
implies the rule above.

Despite the above rules against redeclaration of
variables, the rules of shadowing (§6.4.1) allow
redeclaration in certain nested class declarations (i.e. local classes
(§14.3) and anonymous classes
(§15.9)) as follows:

A formal parameter of a method or constructor
may be shadowed anywhere inside a class declaration nested
within that method or constructor.

A local variable of a method, constructor, or
initializer may be shadowed anywhere inside a class declaration
nested within the scope of the local variable.

A local class declaration may be shadowed
anywhere inside a class declaration nested within the local
class declaration's scope.

An exception parameter may be shadowed anywhere
inside a class declaration nested within the Block of the
catch clause.

A variable declared in
a ResourceSpecification may be shadowed
anywhere inside a class declaration nested within the tryBlock.

Example 6.4-1. Attempted Shadowing Of A Local Variable

Because a
declaration of an identifier as a local variable of a method,
constructor, or initializer block must not appear within the scope of
a parameter or local variable of the same name, a compile-time error
occurs for the following program:

This restriction helps to detect some otherwise very
obscure bugs. A similar restriction on shadowing of members by local
variables was judged impractical, because the addition of a member in
a superclass could cause subclasses to have to rename local
variables. Related considerations make restrictions on shadowing of
local variables by members of nested classes, or on shadowing of local
variables by local variables declared within nested classes
unattractive as well.

This program compiles without error and, when
executed, produces the output:

0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1

6.4.1. Shadowing

Some
declarations may be shadowed in part of their
scope by another declaration of the same name, in which case a simple
name cannot be used to refer to the declared entity.

Shadowing is distinct from
hiding (§8.3, §8.4.8.2,
§8.5, §9.3,
§9.5), which applies only to members which would
otherwise be inherited but are not because of a declaration in a
subclass. Shadowing is also distinct from obscuring
(§6.4.2).

A declaration d
is said to be visible at point p in a
program if the scope of d
includes p, and d is not shadowed by
any other declaration at p.

When the program point we are
discussing is clear from context, we will often simply say that a
declaration is visible.

A
declaration d of a type named n shadows the
declarations of any other types named n that are in scope
at the point where d occurs throughout the scope
of d.

A declaration d of a
field or formal parameter named n shadows, throughout the
scope of d, the declarations of any other variables
named n that are in scope at the point
where d occurs.

A declaration d of a
local variable or exception parameter named n shadows,
throughout the scope of d, (a) the declarations of any
other fields named n that are in scope at the point
where d occurs, and (b) the declarations of any other
variables named n that are in scope at the point
where d occurs but are not declared
in the innermost class in which d is declared.

A
declaration d of a method named n shadows
the declarations of any other methods named n that are in
an enclosing scope at the point where d occurs throughout
the scope of d.

A package
declaration never shadows any other declaration.

A
type-import-on-demand declaration never causes any other declaration
to be shadowed.

A
static-import-on-demand declaration never causes any other declaration
to be shadowed.

A
single-type-import declaration d in a compilation
unit c of package p that imports a type
named n shadows, throughout c, the
declarations of:

any
top level type named n declared in another
compilation unit of p

any
type named n imported by a type-import-on-demand
declaration in c

any
type named n imported by a static-import-on-demand
declaration in c

A
single-static-import declaration d in a compilation
unit c of package p that imports
a field named n shadows the declaration of any
static field named n imported by a
static-import-on-demand declaration in c,
throughout c.

A
single-static-import declaration d in a compilation
unit c of package p that imports
a method named n with signature s
shadows the declaration of any static method named n with
signature s imported by a static-import-on-demand
declaration in c,
throughout c.

A
single-static-import declaration d in a compilation
unit c of package p that imports
a type named n shadows, throughout c,
the declarations of:

any
static type named n imported by a
static-import-on-demand declaration
in c;

any
top level type (§7.6) named n
declared in another compilation unit (§7.3)
of p;

any
type named n imported by a type-import-on-demand
declaration (§7.5.2)
in c.

Example 6.4.1-1. Shadowing of a Field Declaration by a Local Variable Declaration

Since the scope of a class variable includes the
entire body of the class (§8.2), the class
variable x would normally be available throughout
the entire body of the method main. In this
example, however, the class variable x is shadowed
within the body of the method main by the
declaration of the local variable x.

A local variable has as its scope the rest of the
block in which it is declared (§6.3); in this
case this is the rest of the body of the main
method, namely its initializer "0" and the
invocations of System.out.print
and System.out.println.

This means that:

The expression x in the
invocation of print refers to (denotes) the
value of the local variable x.

The invocation of println
uses a qualified name
(§6.6) Test.x, which uses
the class type name Test to access the class
variable x, because the declaration
of Test.x is shadowed at this point and cannot
be referred to by its simple name.

The keyword this can also be used to access a
shadowed field x, using the
form this.x. Indeed, this idiom typically appears
in constructors (§8.8):

Here, the constructor takes parameters having the
same names as the fields to be initialized. This is simpler than
having to invent different names for the parameters and is not too
confusing in this stylized context. In general, however, it is
considered poor style to have local variables with the same names as
fields.

Example 6.4.1-2. Shadowing of a Type Declaration by Another Type Declaration

using the class Vector declared
here in preference to the generic
class java.util.Vector
(§8.1.2) that might be imported on demand.

6.4.2. Obscuring

A simple
name may occur in contexts where it may potentially be interpreted as
the name of a variable, a type, or a package. In these situations, the
rules of §6.5 specify that a variable will be
chosen in preference to a type, and that a type will be chosen in
preference to a package. Thus, it is may sometimes be impossible to
refer to a visible type or package declaration via its simple name. We
say that such a declaration is obscured.

The naming conventions of §6.1
help reduce obscuring, but if it does occur, here are some notes about
what you can do to avoid it.

When package names occur in expressions:

If a package name is obscured by a field
declaration, then import declarations
(§7.5) can usually be used to make
available the type names declared in that package.

If a package name is obscured by a declaration
of a parameter or local variable, then the name of the parameter
or local variable can be changed without affecting other
code.

The first component of a package name is normally
not easily mistaken for a type name, as a type name normally begins
with a single uppercase letter. (The Java programming language does not actually rely
on case distinctions to determine whether a name is a package name or
a type name.)

Obscuring involving class and interface type names
is rare. Names of fields, parameters, and local variables normally do
not obscure type names because they conventionally begin with a
lowercase letter whereas type names conventionally begin with an
uppercase letter.

If a field name obscures a package name, then an
import declaration (§7.5) can usually be
used to make available the type names declared in that
package.

If a field name obscures a type name, then a
fully qualified name for the type can be used unless the type
name denotes a local class (§14.3).

Field names cannot obscure method names.

If a field name is shadowed by a declaration of
a parameter or local variable, then the name of the parameter or
local variable can be changed without affecting other
code.

Obscuring involving constant names is rare:

Constant names normally have no lowercase
letters, so they will not normally obscure names of packages or
types, nor will they normally shadow fields, whose names
typically contain at least one lowercase letter.

6.5. Determining the Meaning of a Name

The meaning
of a name depends on the context in which it is used. The
determination of the meaning of a name requires three steps:

First,
context causes a name syntactically to fall into one of six
categories: PackageName,
TypeName,
ExpressionName,
MethodName,
PackageOrTypeName,
or AmbiguousName.

Second, a name that is initially
classified by its context as
an AmbiguousName or as
a PackageOrTypeName is then reclassified to
be a PackageName,
TypeName, or
ExpressionName.

Third,
the resulting category then dictates the final determination of
the meaning of the name (or a compile-time error if the name has
no meaning).

PackageName:
Identifier
PackageName . Identifier

TypeName:
Identifier
PackageOrTypeName . Identifier

ExpressionName:
Identifier
AmbiguousName . Identifier

MethodName:
Identifier
AmbiguousName . Identifier

PackageOrTypeName:
Identifier
PackageOrTypeName . Identifier

AmbiguousName:
Identifier
AmbiguousName . Identifier

The use of context helps to minimize name conflicts
between entities of different kinds. Such conflicts will be rare if
the naming conventions described in §6.1 are
followed. Nevertheless, conflicts may arise unintentionally as types
developed by different programmers or different organizations
evolve. For example, types, methods, and fields may have the same
name. It is always possible to distinguish between a method and a
field with the same name, since the context of a use always tells
whether a method is intended.

6.5.1. Syntactic Classification of a Name According to Context

A name is
syntactically classified as a PackageName in
these contexts:

The effect of syntactic classification is to
restrict certain kinds of entities to certain parts of
expressions:

The name of a field, parameter, or local
variable may be used as an expression
(§15.14.1).

The name of a method may appear in an expression
only as part of a method invocation expression
(§15.12).

The name of a class or interface type may appear
in an expression only as part of a class literal
(§15.8.2), a qualified this expression
(§15.8.4), a class instance creation
expression (§15.9), an array creation
expression (§15.10), a cast expression
(§15.16), an instanceof expression
(§15.20.2), an enum constant
(§8.9), or as part of a qualified name for
a field or method.

The name of a package may appear in an
expression only as part of a qualified name for a class or
interface type.

6.5.2. Reclassification of Contextually Ambiguous Names

An AmbiguousName is then
reclassified as follows.

If
the AmbiguousName is a simple name, consisting of
a single Identifier:

If
the Identifier appears within the scope
(§6.3) of a local variable declaration
(§14.4) or parameter declaration
(§8.4.1, §8.8.1,
§14.20) or field declaration
(§8.3) with that name, then
the AmbiguousName is reclassified as
an ExpressionName.

Otherwise, if a field of that name is
declared in the compilation unit (§7.3)
containing the Identifier by a single-static-import declaration
(§7.5.3), or by a static-import-on-demand
declaration (§7.5.4) then
the AmbiguousName is reclassified as
an ExpressionName.

Otherwise, if the Identifier appears
within the scope (§6.3) of a top level class
(§8) or interface type declaration
(§9), a local class declaration
(§14.3) or member type declaration
(§8.5, §9.5) with that
name, then the AmbiguousName is reclassified
as a TypeName.

Otherwise, if a type of that name is
declared in the compilation unit (§7.3)
containing the Identifier, either by a single-type-import
declaration (§7.5.1), or by a
type-import-on-demand declaration (§7.5.2),
or by a single-static-import declaration
(§7.5.3), or by a static-import-on-demand
declaration (§7.5.4), then
the AmbiguousName is reclassified as
a TypeName.

Otherwise,
the AmbiguousName is reclassified as
a PackageName. A later step determines
whether or not a package of that name actually exists.

If
the AmbiguousName is a qualified name, consisting
of a name, a ".", and an Identifier, then the name to the left
of the "." is first reclassified, for it is itself
an AmbiguousName. There is then a choice:

If
the name to the left of the "." is reclassified as
a PackageName, then:

If there is a package whose name
is the name to the left of the "." and that package
contains a declaration of a type whose name is the same as
the Identifier, then
this AmbiguousName is reclassified as
a TypeName.

Otherwise,
this AmbiguousName is reclassified as
a PackageName. A later step determines
whether or not a package of that name actually exists.

If
the name to the left of the "." is reclassified as
a TypeName, then:

If the Identifier is the name of
a method or field of the type denoted
by TypeName,
this AmbiguousName is reclassified as
an ExpressionName.

Otherwise, if the Identifier is
the name of a member type of the type denoted
by TypeName,
this AmbiguousName is reclassified as
a TypeName.

Otherwise, a compile-time error
occurs.

If
the name to the left of the "." is reclassified as
an ExpressionName, then let T be the type
of the expression denoted
by ExpressionName.

If the Identifier is the name of
a method or field of the type denoted by T,
this AmbiguousName is reclassified as
an ExpressionName.

Otherwise, if the Identifier is
the name of a member type (§8.5,
§9.5) of the type denoted by T, then
this AmbiguousName is reclassified as
a TypeName.

First of all, the
name org.rpgpoet.Music.wizards.length is classified
as an ExpressionName because it functions as
a PostfixExpression. Therefore, each of the
names:

org.rpgpoet.Music.wizards
org.rpgpoet.Music
org.rpgpoet
org

is initially classified as
an AmbiguousName. These are then
reclassified:

The simple name org is
reclassified as a PackageName (since there
is no variable or type named org in scope).

Next, assuming that there is no class or
interface named rpgpoet in any compilation
unit of package org (and we know that there
is no such class or interface because
package org has a subpackage
named rpgpoet), the qualified
name org.rpgpoet is reclassified as
a PackageName.

Next, because
package org.rpgpoet has an accessible
(§6.6) interface type
named Music, the qualified
name org.rpgpoet.Music is reclassified as
a TypeName.

Finally, because the
name org.rpgpoet.Music is
a TypeName, the qualified
name org.rpgpoet.Music.wizards is
reclassified as an ExpressionName.

6.5.3. Meaning of Package Names

The
meaning of a name classified as a PackageName is
determined as follows.

6.5.3.1. Simple Package Names

If a
package name consists of a single Identifier, then this identifier
denotes a top level package named by that identifier.

If no top
level package of that name is in scope (§6.3),
then a compile-time error occurs.

6.5.3.2. Qualified Package Names

If a
package name is of the form Q.Id,
then Q must also be a package name. The package
name Q.Id names a package that is the member
named Id within the package named
by Q.

If Q does not name an
observable package (§7.4.3),
or Id is not the simple name of an observable
subpackage of that package, then a compile-time error occurs.

6.5.4. Meaning of PackageOrTypeNames

6.5.4.1. Simple PackageOrTypeNames

If
the PackageOrTypeName, Q,
occurs in the scope of a type named Q, then
the PackageOrTypeName is reclassified as
a TypeName.

Otherwise,
the PackageOrTypeName is reclassified as
a PackageName. The meaning of
the PackageOrTypeName is the meaning of the
reclassified name.

6.5.4.2. Qualified PackageOrTypeNames

Given a
qualified PackageOrTypeName of the
form Q.Id, if the type or package denoted
by Q has a member type named Id,
then the qualified PackageOrTypeName name is
reclassified as a TypeName.

Otherwise, it is reclassified as
a PackageName. The meaning of the
qualified PackageOrTypeName is the meaning of the
reclassified name.

6.5.5. Meaning of Type Names

The
meaning of a name classified as a TypeName is
determined as follows.

6.5.5.1. Simple Type Names

If a type
name consists of a single Identifier, then the identifier must occur
in the scope of exactly one visible declaration of a type with this
name, or a compile-time error occurs. The meaning of the type name is
that type.

6.5.5.2. Qualified Type Names

If a
type name is of the form Q.Id,
then Q must be either a type name or a package
name.

If Id names exactly
one accessible type
(§6.6) that is a member of the type or package
denoted by Q, then the qualified type name denotes
that type.

If Id does not name a
member type (§8.5, §9.5)
within Q,
or there is not exactly one accessible
(§6.6) member type named Id
within Q,
or Id names a static member type
(§8.5.1) within Q
and Q is parameterized, then a
compile-time error occurs.

In this example, the
name java.util.Date must denote a type, so we first
use the procedure recursively to determine if java.util is an
accessible type or a package, which it is, and then look to see if the
type Date is accessible in this package.

6.5.6. Meaning of Expression Names

The
meaning of a name classified as an ExpressionName
is determined as follows.

6.5.6.1. Simple Expression Names

If an expression name consists of
a single Identifier, then there must be exactly one declaration
denoting either a local variable, parameter, or field visible
(§6.4.1) at the point at which the Identifier
occurs. Otherwise, a compile-time error occurs.

If the
declaration denotes an instance variable (§8.3),
the expression name must appear within the declaration of an instance
method (§8.4), constructor
(§8.8), instance initializer
(§8.6), or instance variable initializer
(§8.3.2.2). If the expression name appears within
a static method (§8.4.3.2), static initializer
(§8.7), or initializer for a static variable
(§8.3.2.1, §12.4.2), then a
compile-time error occurs.

If the
declaration declares a final variable which
is definitely assigned before the simple expression, the
meaning of the name is the value of
that variable. Otherwise, the meaning of the expression
name is the variable declared by the declaration.

If the
expression name appears in a context where it is subject to assignment
conversion or method invocation conversion or casting conversion, then
the type of the expression name is the declared type of the field,
local variable, or parameter after capture conversion
(§5.1.10).

Otherwise, the type of the expression name is
the declared type of the field, local variable or parameter.

That is, if the expression name appears "on the
right hand side", its type is subject to capture conversion. If the
expression name is a variable that appears "on the left hand side",
its type is not subject to capture conversion.

In this program, the names used as the
left-hand-sides in the assignments
to i, v,
and f denote the local
variable i, the field v, and the
value of f (not the variable f,
because f is a final variable). The example
therefore produces an error at compile time because the last
assignment does not have a variable as its left-hand side. If the
erroneous assignment is removed, the modified code can be compiled and
it will produce the output:

1 2 3

6.5.6.2. Qualified Expression Names

If an
expression name is of the form Q.Id,
then Q has already been classified as a package
name, a type name, or an expression name.

This program encounters two compile-time errors,
because the int variable i has no members, and
because nPoints is not a method of
class Point.

Example 6.5.6.2-2. Qualifying an Expression with a Type Name

Note that expression names may be qualified by type
names, but not by types in general. A consequence is that it is not
possible to access a class variable through a parameterized
type.

For example, given the code:

class Foo<T> {
public static int classVar = 42;
}

the following assignment is illegal:

Foo<String>.classVar = 91; // illegal

Instead, one writes

Foo.classVar = 91;

This does not restrict the Java programming language in any
meaningful way. Type parameters may not be used in the types of static
variables, and so the type arguments of a parameterized type can never
influence the type of a static variable. Therefore, no expressive
power is lost. Technically, the type name Foo above
is a raw type, but this use of raw types is harmless, and does not
give rise to warnings

6.5.7. Meaning of Method Names

The meaning of a name
classified as a MethodName is determined as
follows.

6.5.7.1. Simple Method Names

A simple
method name may appear as the element name in an element-value
pair.

In that
case, the Identifier in an ElementValuePair
must be the simple name of one of the elements of the annotation type
identified by TypeName in the containing
annotation, or a compile-time error occurs.

In other words, the identifier in an element-value
pair must also be a method name in the interface identified
by TypeName.

Otherwise, a simple method name necessarily
appears in the context of a method invocation expression. In that
case, if a method name consists of a single Identifier, then
Identifier is the method name to be used for method
invocation.

The Identifier must name at least one method that is
visible at the point where the Identifier appears
(§6.4.1), or a method imported by a
single-static-import declaration (§7.5.3) or
static-import-on-demand declaration (§7.5.4)
within the compilation unit within which the Identifier appears, or
else a compile-time error occurs by the rules of
§15.12.

Example 6.5.7.1-1. Simple Method Names and Visibility

The following program demonstrates the role of
method visibility when determining which method to invoke.

For the invocation f1(0), only
one method named f1 is visible. It is the
method Test.f1(int), whose declaration is in scope
throughout the body of Test including the anonymous
class declaration. §15.12.1 chooses to search in
class Test since the anonymous class declaration
has no member named f1. Eventually,
Test.f1(int) is resolved.

For the invocation f2(0), two
methods named f2 are visible. First, the
declaration of the method Super.f2(String) is in
scope throughout the anonymous class declaration. Second, the
declaration of the method Test.f2(int) is in scope
throughout the body of Test including the anonymous
class declaration. §15.12.1 chooses to search in
class Super because it has a member
named f2. However, Super.f2(String)
is not applicable to f2(0), so a compile-time error
occurs. Note that class Test is not
searched.

For the invocation f3(0), three
methods named f3 are visible. First and second, the
declarations of the methods Super.f3(String)
and Super.f3(int,int) are in scope throughout the
anonymous class declaration. Third, the declaration of the
method Test.f3(int) is in scope throughout the body
of Test including the anonymous class
declaration. §15.12.1 chooses to search in
class Super because it has a member
named f3. However, Super.f3(String)
and Super.f3(int,int) are not applicable
to f3(0), so a compile-time error occurs. Note that
class Test is not searched.

Choosing to search a nested class's superclass
hierarchy before than the lexically enclosing scope is called the
"comb rule" (§15.12.1).

6.5.7.2. Qualified Method Names

A qualified method name can
only appear in the context of a method invocation expression.

If a
method name is of the form Q.Id,
then Q has already been classified as a package
name, a type name, or an expression name:

If Q is a package
name, then a compile-time error occurs.

Otherwise, Q is a
type name or an expression name.

Id is the method
name to be used for method invocation.

If Q is a
type name, then Id must name at least one
static method of the type Q, or a
compile-time error occurs by the rules of
§15.12.

If Q is
an expression name, then let T be the type of the
expression Q. Id must name
at least one method of the type T, or a compile-time error
occurs by the rules of
§15.12.

Like expression names, method names may be qualified
by type names, but not by types in general. The implications are
similar to those for expression names as discussed in
§6.5.6.2.

6.6. Access Control

The Java programming language provides
mechanisms for access control, to prevent the
users of a package or class from depending on unnecessary details of
the implementation of that package or class. If access is permitted,
then the accessed entity is said to
be accessible.

Note that accessibility is a
static property that can be determined at compile time; it depends
only on types and declaration modifiers.

Qualified names are a means of
access to members of packages and reference types. When the name of
such a member is classified from its context
(§6.5.1) as a qualified type name (denoting a
member of a package or reference type, §6.5.5.2)
or a qualified expression name (denoting a member of a reference type,
§6.5.6.2), access control is applied.

For example, a
single-type-import statement (§7.5.1) must use a
qualified type name, so the type name being imported must be
accessible from the compilation unit containing the import
statement. As another example, a class declaration may use a qualified
type name for a superclass (§8.1.5), and again
the qualified type name must be accessible.

Some obvious
expressions are "missing" from context classification in
§6.5.1: field access on
a Primary (§15.11.1), method
invocation on a Primary
(§15.12), and the instantiated class in a
qualified class instance creation (§15.9). Each
of these expressions uses identifiers, rather than names, for the
reason given in §6.2. Consequently, access
control to members (whether fields, methods, types) is
applied explicitly by field access expressions,
method invocation expressions, and qualified class instance creation
expressions. (Note that access to a field may also be denoted by a
qualified name occuring as a postfix expression.)

Note that
qualified names, field access expressions, method invocation
expressions, and qualified class instance creation expressions are
syntactically similar in that a "." token appears, preceded by
some indication of a package, type, or expression having a type, and
followed by an Identifier that names a member of the package or
type. (A new token intercedes between the . and the Identifier
in a qualified class instance creation expression.)

Many statements
and expressions allow the use of types rather than type names. For
example, a class declaration may use a parameterized type
(§4.5) to denote a superclass. Because a
parameterized type is not a qualified type name, it is necessary for
the class declaration to explicitly perform access control for the
denoted superclass. Consequently, most of the statements and
expressions that provide contexts in §6.5.1 to
classify a TypeName must also perform their own
access control checks.

Beyond access to
members of a package or reference type, there is the matter of access
to constructors of a reference type. Access control must be checked
when a constructor is invoked explicitly or implicitly. Consequently,
access control is checked by an explicit constructor invocation
statement (§8.8.7.1) and by a class instance
creation expression (§15.9.3). These "manual"
checks are necessary because §6.5.1 ignores
explicit constructor invocation statements (because they reference
constructor names indirectly) and is unaware of the distinction
between the class type denoted by an unqualified class instance
creation expression and a constructor of that class type. Also,
constructors do not have qualified names, so we cannot rely on access
control being checked during classification of qualified type
names.

Accessibility affects inheritance of class members
(§8.2), including hiding and method overriding
(§8.4.8.1).

6.6.1. Determining Accessibility

A
package is always accessible.

If a
class or interface type is declared public, then it may be
accessed by any code, provided that the compilation unit
(§7.3) in which it is declared is
observable.

If
a top level class or interface type is not declared public,
then it may be accessed only from within the package in which it
is declared.

An
array type is accessible if and only if its element type is
accessible.

A
member (class, interface, field, or method) of a reference
(class, interface, or array) type or a constructor of a class
type is accessible only if the type is accessible and the member
or constructor is declared to permit access:

If the member or constructor is
declared public, then access is permitted.

All members of interfaces are
implicitly public.

Otherwise, if the member or
constructor is declared protected, then access is
permitted only when one of the following is true:

Access to the member or
constructor occurs from within the package containing
the class in which the protected member or constructor
is declared.

Otherwise, if the member or
constructor is declared private, then access is permitted
if and only if it occurs within the body of the top level
class (§7.6) that encloses the
declaration of the member or constructor.

Otherwise, we say there is
default access, which is permitted only
when the access occurs from within the package in which the
type is declared.

The class type PointVec is
not public and not part of the public interface of the
package points, but rather can be used only
by other classes in the package.

The class type Point is
declared public and is available to other packages. It is part
of the public interface of the
package points.

The
methods move, getX,
and getY of the
class Point are declared public and so are
available to any code that uses an object of
type Point.

The fields x
and y are declared protected and are
accessible outside the package points only in
subclasses of class Point, and only when they
are fields of objects that are being implemented by the code
that is accessing them.

See §6.6.2 for an example
of how the protected access modifier limits access.

Example 6.6-2. Access to public Fields, Methods, and Constructors

A public class member or constructor is accessible
throughout the package where it is declared and from any other
package, provided the package in which it is declared is observable
(§7.4.3). For example, in the compilation
unit:

the public class Point has as
public members the move method and
the moves field. These public members are
accessible to any other package that has access to
package points. The fields x
and y are not public and therefore are accessible
only from within the package points.

Example 6.6-3. Access to public and Non-public Classes

If a class lacks the public modifier, access to
the class declaration is limited to the package in which it is
declared (§6.6). In the example:

two classes are declared in the compilation
unit. The class Point is available outside the
package points, while the
class PointList is available for access only within
the package. Thus a compilation unit in another package can
access points.Point, either by using its fully
qualified name:

If none of the access modifiers public,
protected, or private are specified, a class member or constructor
is accessible throughout the package that contains the declaration of
the class in which the class member is declared, but the class member
or constructor is not accessible in any other package.

If a public class has a method or constructor with
default access, then this method or constructor is not accessible to
or inherited by a subclass declared outside this package.

then a subclass in another package may declare an
unrelated move method, with the same signature
(§8.4.2) and return type. Because the
original move method is not accessible from
package morepoints, super may
not be used:

Because move
of Point is not overridden
by move in PlusPoint, the
method moveAlso in Point never
calls the method move
in PlusPoint. Thus if you delete
the super.move call
from PlusPoint and execute the test program:

it terminates normally. If move
of Point were overridden by move
in PlusPoint, then this program would recurse
infinitely, until a StackOverflowError occurred.

Example 6.6-5. Access to private Fields, Methods, and Constructors

A private class member or constructor is
accessible only within the body of the top level class
(§7.6) that encloses the declaration of the
member or constructor. It is not inherited by subclasses. In the
example:

the private
members ID, masterID,
and setMasterID may be used only within the body of
class Point. They may not be accessed by qualified
names, field access expressions, or method invocation expressions
outside the body of the declaration
of Point.

6.6.2. Details on protected Access

A protected member or
constructor of an object may be accessed from outside the package in
which it is declared only by code that is responsible for the
implementation of that object.

6.6.2.1. Access to a protected Member

Let C
be the class in which a protected member is declared. Access is
permitted only within the body of a subclass S of C.

In
addition, if Id denotes an instance field or
instance method, then:

If
the access is by a qualified name Q.Id,
where Q is
an ExpressionName, then the access is
permitted if and only if the type of the
expression Q is S or a
subclass of S.

If
the access is by a field access
expression E.Id, where E
is a Primary expression, or by a method
invocation
expression E.Id(. . .),
where E is a Primary
expression, then the access is permitted if and only if the type
of E is S or a subclass
of S.

More information about access to protected members
can be found in Checking Access to Protected Members in the
Java Virtual Machine by Alessandro Coglio, in
the Journal of Object Technology, October
2005.

6.6.2.2. Qualified Access to a protected Constructor

Let C
be the class in which a protected constructor is declared and
let S be the innermost class in whose declaration the use
of the protected constructor occurs. Then:

If
the access is by a superclass constructor
invocation super(. . .) or by a qualified
superclass constructor invocation of the
form E.super(. . .),
where E is a Primary
expression, then the access is permitted.

If
the access is by an anonymous class instance creation expression
of the form new C(. . .){...} or by a
qualified class instance creation expression of the
form E.new C(. . .){...},
where E is a Primary
expression, then the access is permitted.

Otherwise, if the access is by a
simple class instance creation expression of the
form new C(. . .) or by a qualified class
instance creation expression of the
form E.new C(. . .),
where E is a Primary
expression, then the access is not permitted.

A protected constructor can be
accessed by a class instance creation expression (that does not
declare an anonymous class) only from within the package in
which it is defined.

A compile-time error occurs in the
method delta here: it cannot access the protected
members x and y of its
parameter p, because
while Point3d (the class in which the references to
fields x and y occur) is a
subclass of Point (the class in
which x and y are declared), it
is not involved in the implementation of a Point
(the type of the parameter p). The
method delta3d can access the protected members
of its parameter q, because the
class Point3d is a subclass
of Point and is involved in the implementation of
a Point3d.

The method delta could try to
cast (§5.5, §15.16) its
parameter to be a Point3d, but this cast would
fail, causing an exception, if the class of p at
run time were not Point3d.

A compile-time error also occurs in the
method warp: it cannot access the protected
member z of its parameter a,
because while the class Point (the class in which
the reference to field z occurs) is involved in the
implementation of a Point3d (the type of the
parameter a), it is not a subclass
of Point3d (the class in which z
is declared).

6.7. Fully Qualified Names and Canonical Names

Every primitive type,
named package, top level class, and top level interface
has a fully qualified name:

The fully qualified name
of a primitive type is the keyword for that primitive type,
namely byte, short, char, int, long, float,
double, or boolean.

The fully qualified name
of a named package that is not a subpackage of a named package
is its simple name.

The fully qualified name
of a named package that is a subpackage of another named package
consists of the fully qualified name of the containing package,
followed by ".", followed by the simple (member) name of the
subpackage.

The fully qualified name
of a top level class or top level interface that is declared in
an unnamed package is the simple name of the class or
interface.

The fully qualified name
of a top level class or top level interface that is declared in
a named package consists of the fully qualified name of the
package, followed by ".", followed by the simple name of the
class or interface.

Each member class, member
interface, and array type may have a fully
qualified name:

A member class or member
interface M of another class or
interface C has a fully qualified name if and only
if C has a fully qualified name.

In that case, the fully
qualified name of M consists of the fully qualified
name of C, followed by ".", followed by the simple name
of M.

An array type has a fully
qualified name if and only if its element type has a fully
qualified name.

In that case, the fully
qualified name of an array type consists of the fully qualified
name of the component type of the array type followed by
"[]".

A local class does not have a
fully qualified name.

Example 6.7-1. Fully Qualified Names

The fully qualified name of the type long is
"long".

The fully qualified name of the package
java.lang is "java.lang" because it is
subpackage lang of
package java.

The fully qualified name of the class Object,
which is defined in the package java.lang, is
"java.lang.Object".

The fully qualified name of the
interface Enumeration, which is defined in
the package java.util, is
"java.util.Enumeration".

The fully qualified name of the type "array of
double" is "double[]".

The fully qualified name of the type "array of
array of array of array of String" is
"java.lang.String[][][][]".

the fully qualified name of the
type Point is "points.Point";
the fully qualified name of the type PointVec is
"points.PointVec"; and the fully qualified name of
the type of the field vec of
class PointVec is
"points.Point[]".

Every primitive type,
named package, top level class, and top level interface
has a canonical name:

For every primitive
type, named package, top level class,
and top level interface, the canonical name is the same as the
fully qualified name.

Each member class, member
interface, and array type may have a canonical
name:

A member class or member
interface M declared in another class C has a
canonical name if and only if C has a canonical name.

In that case, the
canonical name of M consists of the canonical name of
C, followed by ".", followed by the simple name
of M.

An array type has a
canonical name if and only if its component type has a canonical
name.

In that case, the
canonical name of the array type consists of the canonical name of
the component type of the array type followed by
"[]".

A local class does not have a
canonical name.

Example 6.7-2. Fully Qualified Names v. Canonical Name

The difference between a fully qualified name and a
canonical name can be seen in code such as:

package p;
class O1 { class I {} }
class O2 extends O1 {}

Both p.O1.I
and p.O2.I are fully qualified names that denote
the member class I, but
only p.O1.I is its canonical name.