Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4689050

implicit outer instance for constructing inner class: how is it selected?

    XMLWordPrintable

Details

    • Bug
    • Resolution: Future Project
    • P4
    • None
    • 1.4.0
    • specification
    • None
    • generic
    • solaris_8

    Description

      A subtle point regarding how the language selects the implicit outer instance
      for an inner class creation expression has arisen in the context of compiler
      bugs 4635044 and 4494653. The JLS disagrees with every Java language
      implementation that I could find, and I suggest that we consider changing the
      language specification instead of all the compilers (and perhaps any user code
      and test cases that depend on the compilers current behavior). I have tested
      javac 1.2, javac 1.3 and later, EDG's compiler, jikes, and the aspectj compiler.
      The all fail the following two test cases in precisely the same way. Based on
      the current wording in the JLS, the diagnostic generated by the compiler for
      4494653 is misleading.

      The current wording is in 15.9.2 selects the nearest enclosing instance of which
      the class being created is a member. Existing compilers, on the other hand,
      select the nearest enclosing class that is a subtype of the type containing the
      class being created. There is only a difference when the class being created
      is not inherited either because of protection or because it is hidden. It is
      unfortunate that the Java language is defined in such a way that a distinction
      between these two choices is possible. The two enclosed test cases, based on
      the current JLS2 wording, illustrate these issues. All compilers fail them.

      While the specification is clear in this regard, I wonder if it would not be
      better to change the language specification to bring it in line with current
      practice rather than the other way around. In order to address the related
      compiler bugs, I will need a definitive statement one way or another on whether
      the JLS2 will be adjusted.


      /** Check that non-inheritance (private) prevents enclosing class selection. */
      class T1 {
          boolean isT() { return true; }
          private class Middle extends T1 {
              boolean isT() { return false; }
              boolean enclIsT() { return T1.this.isT(); }
              class Inner {}
              boolean check() {
                  return /*T1.this.*/new T1.Middle().enclIsT();
              }
          }
          public static void main(String[] args) {
              T1 t = new T1();
              Middle m = t.new Middle();
              if (!m.check()) throw new Error();
          }
      }

      /** Check that hiding prevents enclosing class selection. */
      class T2 {
          boolean isT() { return true; }
          class Middle {
              boolean enclIsT() { return T2.this.isT(); }
          }
          class X extends T2 {
              boolean isT() { return false; }
              class Middle {} // hide T2.Middle
              boolean check() {
                  return /*T2.this.*/new T2.Middle().enclIsT();
                  // error: javac uses X.this instead of T2.this, above
              }
          }
          public static void main(String[] args) {
              T2 t = new T2();
              X x = t.new X();
              if (!x.check()) throw new Error();
          }
      }

      Attachments

        Issue Links

          Activity

            People

              abuckley Alex Buckley
              gafter Neal Gafter
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: