Accessing Members in Enclosing Context – Nested Type Declarations

Accessing Members in Enclosing Context

Static member classes do not have a this reference, as they do not have any notion of an enclosing instance. This means that any code in a static member class can only directly access static members in its enclosing context. Trying to access any instance members directly in its enclosing context results in a compile-time error.

Figure 9.2 is a class diagram that illustrates static member classes and interfaces. These are shown as members of the enclosing context, with the {static} tag to indicate that they are static members. Since they are members of a class or an interface, their accessibility can be specified exactly like that of any other member of a class or interface: Class members can be declared with any of the four access levels (public, protected, package, private), but interface members are always implicitly public. The classes from the diagram are implemented in Example 9.4.

Figure 9.2 Static Member Classes and Interfaces

Example 9.4 Accessing Members in Enclosing Context (Static Member Classes)

Click here to view code image

// File: ListPool.java
public class ListPool {                                 // Top-level class
  public void messageInListPool() {                     // Instance method
    System.out.println(“This is a ListPool object.”);
  }
  private static class MyLinkedList {                   // (1) Static member class
    private static int maxNumOfLists = 100;             // Static field
    private int currentNumOfLists;                      // Instance field
    public static void messageInLinkedList() {          // Static method
      System.out.println(“This is MyLinkedList class.”);
    }
    interface ILink { int MAX_NUM_OF_NODES = 2000; }// (2) Static member interface
    protected static class Node implements ILink {  // (3) Static member class
private int max = MAX_NUM_OF_NODES;           // (4) Instance field
      public void messageInNode() {                 // Instance method
//      int currentLists = currentNumOfLists;// (5) Not OK. Access instance field
                                             //             in outer class
        int maxLists = maxNumOfLists;     // Access static field in outer class
        int maxNodes = max;               // Access instance field in member class
//      messageInListPool();    // (6) Not OK. Call instance method in outer class
        messageInLinkedList();  // (7) Call static method in outer class
      }
      public static void main(String[] args) {
        int maxLists = maxNumOfLists;    // (8) Access static field in outer class
//      int maxNodes = max;   // (9) Not OK. Access instance field in member class
        messageInLinkedList();// (10) Call static method in outer class
      }
    }  // Node
  }  // MyLinkedList
} // ListPool

Compiling and running the program:

Click here to view code image

>
javac ListPool.java
>
java ListPool$MyLinkedList$Node
This is MyLinkedList class.

Example 9.4 demonstrates direct access of members in the enclosing context of the static member class Node defined at (3). The class Node implements the static member interface ILink declared at (2). The initialization of the instance field max at (4) is valid, since the field MAX_NUM_OF_NODES, defined in the outer interface ILink at (2), is implicitly static. The compiler will flag an error at (5) and (6) in the instance method messageInNode() because direct access to instance members in the enclosing context is not permitted by any method in a static member class. It will also flag an error at (9) in the method main() because a static method cannot directly access instance fields in its own class. The statements at (8) and (10) can directly access static members in the enclosing context. The references in these two statements can also be specified using qualified names.

Click here to view code image

int maxLists = ListPool.MyLinkedList.maxNumOfLists;              // (8′)
ListPool.MyLinkedList.messageInLinkedList();                     // (10′)

Note that a static member class can define both static and instance members, like any other top-level class. However, its code can only directly access static members in its enclosing context.

Example 9.4 also illustrates that static member types when declared as class members can have any access level. In the class ListPool, the static member class MyLinkedList at (1) has private access, whereas its static member interface ILink at (2) has package access and its static member class Node at (3) has protected access.

The class Node defines the method main() which can be executed by the following command:

Click here to view code image

>
java ListPool$MyLinkedList$Node

Note that the class Node in the command line is specified using the qualified name of the class file minus the extension.

Leave a Reply

Your email address will not be published. Required fields are marked *