Java Quick Reference
  Language Fundamentals
  Operators and Assignments
  Flow Control and Exceptions
  Declarations and Access Control
  Garbage Collection
  Overloading and Overriding
  Threads
  The java.lang Package
  The java.util Package
  The java.awt Package
  The java.io Package
  References
  Miscellaneous Notes
  Tips & Traps
  Mock Exams

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:
  1. if used in a code block, for-loop, or in a catch clause, search is for a local variable within the enclosing construct
  2. if in a method or constructor, searches for a matching parameter
  3. search continues for a class or interface member, including inherited members
  4. 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.
  5. explicitly named imported types
  6. other types declared in the same package
  7. implicitly named imported types
  8. 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



Access Modifiers Special Modifiers this and super Scope Inheritance Access Control