|
|
Declarations and Access Control - Scope
- names are used to identify entities declared in a program ie classes, methods, variables, parameters, etc
- each name or identifier occupies a particular namespace
- every declaration has a scope; the areas of a program from which it can be accessed by its simple name
| Declaration |
Scope (accessible from) |
| package |
all compilation units within the package |
| import |
all the classes and interfaces within the compilation unit (source code file) |
| class or interface |
all other declarations within the same file |
| label |
the statements immeadiately enclosed by the labeled statement ie if a loop is labelled, everything declared within the loop-construct has access to the label |
| member |
the body of the class and anything declared within the class |
| parameter |
the body of the method or constructor |
| local variable |
the code block in which the declaration occurs |
| local class |
the enclosing block including the local class body |
| local variable in a for-loop initializer |
the body of the for-loop |
| parameter in a catch clause |
the body of the catch clause |
Order of searching for an identifier (JPL pg 113 and JLS §6.5)
- when a name (identifier) is used; the meaning, or scope, of it's name is searched for based on where it appears in the code starting with:
- if used in a code block, for-loop, or in a catch clause, search is for a local variable within the enclosing construct
- if in a method or constructor, searches for a matching parameter
- search continues for a class or interface member, including inherited members
- if its a nested type, searches enclosing block or class. If its a static type, only static members of enclosing blocks or classes are searched.
- explicitly named imported types
- other types declared in the same package
- implicitly named imported types
- packages on the host system
Shadowing (JLS §6.3.1)
- Because of the way identifiers are looked up; shadowing declarations can occur
- For example, a field declaration can be shadowed by a local variable declaration
class TestShadowing {
static int x = 1; // field variable
public static void main(String[] args) {
int x = 0; // local variable
System.out.println("x = " + x);
System.out.println("TestShadowing.x = " + TestShadowing.x)
}
}
Output:
x = 0
TestShadowing.x = 1
- because the identifier x is used within a code block main() a search is made for a declaration of x within the body of main(). As one is found, int x = 0, the simple identifier name x is assumed to be within scope as a local variable
- to access the field variable x, you must use its fully-qualified name TestShadowing.x
| Note |
- it was not necessary to instantiate an instance of the TestShadowing object to access the static field variable. If x had been an instance variable it would have been necessary to create a new instance of TestShadowing and use it's reference to access x
|
Hiding
- Shadowing is not the same as hiding
- hiding applies to members that would normally be inherited but are not because of a declaration of the same identifier in a subclass (JLS § 6.1.3)
class SuperA {
int x = 10;
}
class SubA extends SuperA {
int x = 20; // hides x in superclass
}
- a method can hide a method in the superclass by overriding it
| static Methods cannot be overridden |
- a method cannot override a static method in the superclass; however, it can hide it by using the same declaration
class SuperA {
static void method2() {
}
}
class SubA extends SuperA() {
void method2() {
// declaration causes a compile-error
}
static void method2() {
// compiles ok
}
}
- static methods are hidden vs overridden as the JLS states they "cannot be overridden" so the compiler never compares subclass method declarations to static superclass method declarations.
- a static method in a subclass cannot hide an instance method in the superclass (JLS §8.4.6.2)
class SuperA {
void method1() {
}
}
class SubA extends SuperA() {
static void method1() {
// compile-error
}
}
|
- a hidden method can be accessed by using super(), casting to the superclass or using the methods fully qualified name
(JLS §8.4.6.2)
((SuperA)y).method2(); // cast to access hidden method
- instance variables can hide static and non-static variables in the superclass (JLS §8.4.6.1)
Obscuring (JLS §6.3.2)
- there may be times when a simple name could be interpreted as a variable, a type or a package
- based on the rules, a variable will be chosen before a type, and a type before a package
- in such situations a declaration is said to be obscured
- following naming conventions helps to avoid obscuring
(see Naming conventions).
Also See
Tech Tip on Sun Site re: Shadowing, hiding, etc
Example Code
|