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
}
}
}
}
}
}
I think that Mark Rotteveel is correct: the rules in 6.4 are actually relaxing the normal 8.1 rule about nested classes. This is clear from the (non-normative) paragraph that follows the 8.1 rule that you quoted:
Clearly, the 6.4 rule is not redundant. It is allowing a form of shadowing that is otherwise forbidden (by 8.1). To the extent1 that 6.4 contradicts 8.1, the text above implies that intended meaning is that 6.4 should override 8.1 for local classes.
1 - There may also be a way of reading 6.4 so that it doesn't contradict 8.1; e.g. some fine distinction between enclosing classes and enclosing methods. However, I couldn't find a convincing justification for that. It is also possible that the facial contradiction is due to an editorial issue, and the spec and/or the compiler is wrong.