JDK-8050938 : 4.7.9.1: Clarify relationship of Identifiers to class names
  • Type: Bug
  • Component: specification
  • Sub-Component: vm
  • Affected Version: 8
  • Priority: P5
  • Status: Closed
  • Resolution: Not an Issue
  • Submitted: 2014-07-16
  • Updated: 2014-07-18
  • Resolved: 2014-07-18
Related Reports
Relates :  
Description
ClassTypeSignatures are essentially sequences of dot-delimited "Identifiers", with some optional type arguments thrown in.  However, the correspondence between Identifiers and class names is unclear.

There is this: "the terminal symbol Identifier is used to denote the name of a type ... as generated by the Java compiler"

But the compiler-generated name of an inner class may be considered "Outer$Inner" or "Outer.Inner", depending on context.

Longstanding behavior is as follows:
- Inner classes of parameterized class types are encoded with, e.g., 'LOuter<TT;>.Inner;'
- Inner classes of non-generic classes are encoded with, e.g., 'LOuter$Inner;'
- Inner classes of raw class types are encoded with, e.g., 'LOuter$Inner;'
- Inner classes multiple levels deep may mix delimiters, e.g. 'LA$B<TT;>.C.D;'

JVMS 4.7.9 limits its rules about correctness to syntax; but, to some extent, it endorses the semantic checks performed by java.lang.reflect. In the Oracle JDK, this includes that every class mentioned before a '.' symbol has the correct number of type arguments. Hence, the GenericSignatureFormatError prompting JDK-8037934, which complains that, where Outer is generic, 'LOuter.Inner;' is not well-formed (the type arguments are missing).

So, in general, both '$' and '.' may be used as delimiters, although type arguments must precede a '.' (or ';'), and raw types must precede a '$' (or '.').  It may be useful to simply state informally in 4.7.9.1 that it is acceptable to use '$' in the name of an inner class.
Comments
A class type signature represents the Java language view of a type. Given a non-generic nested class Outer.Inner, I expect the class type signature to utter "Outer.Inner" not "Outer$Inner". I thought it was obvious in 4.7.9.1 that 'Identifier' denotes the _simple_ name of a type, field, method, formal parameter, local variable, or type variable. '$' is legal in such a simple name, so the class type signature of "class A$B {...}" would be "LA$B;" - an L, then one SimpleClassTypeSignature, then one semicolon. That might confuse other parts of Core Reflection, but it's a legal class type signature. I don't see that any JVMS change is necessary,
16-07-2014