javajls

What is the meaning of the following rule in JLS if another rule makes it redundant?


In JLS 17, Section 6.4, it says (emphasis mine):

It is a compile-time error if the name of a local class or interface C is used to declare a new local class or interface within the scope of C, unless the new local class or interface is declared within a class or interface declaration appearing within the scope of C

Meanwhile in Section 8.1:

It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.

Although logically there is no contradiction, I wonder what is the point of having that "unless" clause in the first rule when the second one is going to result in compilation error anyway when the condition for "unless" is not satisfied? Perhaps I am missing something?

For example:

class Test {
  public void foo() {
    class C {
      public void bar() {
        class SomeNested {
          public void xyz() {
            class C{} // Section 6.4 says nothing what happens in this case. Section 8.1 results in compilation error
          }
        }
      }
    }
  }
}

Solution

  • Quoting Dan Smith's reply which explains what case rule 6.4 is actually covering:

    The 6.4 rule applies to the entire scope of a local class—that is, including the rest of the method body/block following its declaration. The 8.1 rule only applies to the body of the class itself.

    So, for example:

    void foo() {
        class C {}
        new C();
        class C {} // error, per 6.4
        Object o = new Object() {
            void m() {
                class C {} // no error, per 6.4
            }
        }; }
    

    There is an interesting overlap between the "unless" clause of 6.4 and the rule in 8.1. But in general these rules are handling different things.

    So, there is no contradiction, neither the rule is redundant.