Static Local Types – Nested Type Declarations

9.5 Static Local Types

It is possible to declare local interfaces, local enum types, and local record classes. However, these local nested types are implicitly static—as opposed to local classes that are never static. A local class declared in a static context is not the same as a static local type, and they are compared next.

Since these local nested types are implicitly static, this has implications for these types, as listed below. We illustrate these implications for a static local record class in Example 9.13, but they apply equally to local interfaces and local enum types as well.

  • A local record class can be instantiated with the new operator without specifying an immediately enclosing instance. Interfaces and enum types cannot be instantiated with the new operator.

At (10) in Example 9.13, an instance of the static local record class is created without passing a reference to the enclosing object.

  • Static local types can only access static members in the enclosing context—this is the same as local classes declared in static context, whereas local classes declared in non-static context can access all members in the enclosing context.

In Example 9.13, it is possible to access the static field in the enclosing class in the declaration of the local record class at (7) and (9), but it is not possible to access non-static fields as shown at (8).

  • Static local types cannot access any local variables in the enclosing method—in contrast to local classes that can access (effectively) final local variables in the enclosing method.

In Example 9.13, it is not possible to access any local variables, as shown at (5) and (6), in the enclosing method.

Example 9.13 Defining Static Local Record Classes

Click here to view code image

// File: LocalTypesClient.java
class LocalTypes {                     // Top-level Class
  private int nsf;                     // (1) Non-static field
  private static int sf;               // (2) Static field
  void nonStaticMethod(final int fp) { // (3) Non-static Method. Final parameter.
    int lv = 20;                       // (4) Local variable
    record StaticLocalRecord(int val) { // Static local record
      // Cannot access local variables:
//    static int f1 = fp;  // (5) Cannot access final param from enclosing method.
//    static int f2 = lv;  // (6) Cannot access effectively final local variable
                           //     from enclosing method.
      // Can only access static fields in enclosing context:
      static int f3 = sf;         // (7) Access static field in enclosing context.

      void printFieldsFromEnclosingContext() {
//      System.out.println(nsf);  // (8) Cannot access non-static field
                                  //     in enclosing context.
        System.out.println(sf);   // (9) Access static field in enclosing context.
      }
    }
    // (10) Create local record. No enclosing instance passed to the constructor.
    StaticLocalRecord lrRef = new StaticLocalRecord(100);
    System.out.println(“Value: ” + lrRef.val());
  } // nonStaticMethod
}
public class LocalTypesClient {
  public static void main(String[] args) {
    new LocalTypes().nonStaticMethod(1000);    // (10)
  }
}

Output from the program:

Value: 100

Leave a Reply

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