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

Cannot create an anonymous inner of anonymous class

XMLWordPrintable

    • hopper
    • generic
    • generic



      Name: tb29552 Date: 12/15/2000


      /*
      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

      Javac 1.3 refuses to compile this valid file, with some rather cryptic error
      messages:
      */

      class A {
          class B {
          }
          public static void main(String[] args) {
              new A(){}.new B(){};
          }
      }

      /*

      A.java:4: cannot resolve symbol
      symbol: class B
          new A(){}.new B(){};
                        ^
      A.java:4: (<anonymous <any>>) in cannot be applied to (<anonymous A>)
          new A(){}.new B(){};
                    ^
      2 errors

      Quoting from JLS 15.9.1,
      "Otherwise, the class instance creation expression is a qualified class instance
      creation expression. Let T be the name of the Identifier after the new token. It
      is a compile-time error if T is not the simple name (?6.2) of an accessible
      (?6.6) non-final inner class (?8.1.2) that is a member of the compile-time type
      of the Primary. It is also a compile-time error if T is ambiguous (?8.5). An
      anonymous direct subclass of the class named by T is declared. The body of the
      subclass is the ClassBody given in the class instance creation expression. The
      class being instantiated is the anonymous subclass."

      In my example, the first instance creation expression generates <anonymous A>
      extends A. This instance inherits the accessible inner class A.B. The second
      instance creation has B as the simple name T of the specs, the compile-time
      type <anonymous A> for the Primary. Sure enough, there is an accessible,
      non-final member B in the type of the primary, since <anonymous A>.B is an alias
      for the canonical name A.B. Therefore, the expression should generate the class
      <anonymous A>.<anonymous B> extends A.B.

      The related sequence,
      new A(){}.new B();
      compiles, demonstrating that the type <anonymous A>.B is accessible.

      In a similar manner, this class also fails, while making the second instance
      creation non-anonymous compiles:
      class C {
        public static void main(String[] args) {
          new C(){
            class D {}
          }.new D(){};
        }
      }

      Here, the first creation expression creates <anonymous C> extends C, and its
      inner class <anonymous C>.D. The second expression refers to the simple name D
      inside the compile-time type <anonymous C>, which exists. The result should
      thus be <anonymous C>.<anonymous D> extends <anonymous C>.D.
      */

      (Review ID: 113551)
      ======================================================================

            gafter Neal Gafter (Inactive)
            tbell Tim Bell
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: