statement. Then local variables declared in any enclosing code block. This applies recursively up to
the method containing the block, or until there is no enclosing block (as in the case of an initialization
block).
- If the code is in a method or constructor, the parameters to the method or constructor.
- A field of the class or interface, including any accessible inherited fields.
If the type is a nested type, a variable in the enclosing block or field of the enclosing class. If the type
is a static nested type, only static fields of an enclosing type are searched. This search rule is applied
successively to any enclosing blocks and types further out.
4.
- A static field of a class, or interface, specifically declared in a static import statement.
- A static field of a class, or interface, declared in a static import on demand statement.
For method names a similar process as for fields is followed, but starting at step 3, searching for methods in
the current class or interface. There are special rules for determining how members of a class are accessed, as
you'll see in "Member Access" on page 223.
The order of searching determines which declaration will be found. This implies that names declared in outer
scopes can be hidden by names declared in inner scopes. And that means, for example, that local variable
names can hide class member names, that nested class members can hide enclosing instance members, and
that locally declared class members can hide inherited class membersas you have already seen.[9]
[9] Technically, the term hiding is reserved for this last casewhen an inherited member is
hidden by a locally declared memberand the other situations are referred to as shadowing.
This distinction is not significant for this book so we simply refer to "hiding."
Hiding is generally bad style because a human reading the code must check all levels of the hierarchy to
determine which variable is being used. Yet hiding is permitted in order to make local code robust. If hiding
outer variables were not allowed, adding a new field to a class or interface could break existing code in
subtypes that used variables of the same name. Scoping is meant as protection for the system as a whole rather
than as support for reusing identifier names.
To avoid confusion, hiding is not permitted in nested scopes within a code block. This means that a local
variable in a method cannot have the same name as a parameter of that method; that a for loop variable
cannot have the same name as a local variable or parameter; and that once there is a local variable called, say,
über, you cannot create a new, different variable with the name über in a nested block.
{
int über = 0;
{
int über = 2; // INVALID: already defined
// ...
}
}
However, you can have different (non-nested) for loops in the same block, or different (non-nested) blocks
in the same method, that do declare variables with the same name.
If a name appears in a place where a type name is expected, then the different type scopes must be searched
for that name. Type scopes are defined by packages. The search order is as follows:
- The current type including inherited types.
- A nested type of the current type.
- Explicitly named imported types.
- Other types declared in the same package.
- Implicitly named imported types.