Question

The most upvoted answer to this question suggests searching class-files with specific names in specific folders, as a workaround for reflecting anonymous inner classes. In which document (if any) are the names and locations of Java class-files specified?

The VM-spec contains a detailed specification of the format of class-files, but there seems to be no specification of how they should be named and where they should be stored. Likewise, the language-spec does not seem to touch on this subject.

Était-ce utile?

La solution

From the source code of the Class class (getSimpleName method) :

 1137           // According to JLS3 "Binary Compatibility" (13.1) the binary
 1138           // name of non-package classes (not top level) is the binary
 1139           // name of the immediately enclosing class followed by a '$' followed by:
 1140           // (for nested and inner classes): the simple name.
 1141           // (for local classes): 1 or more digits followed by the simple name.
 1142           // (for anonymous classes): 1 or more digits.

The mentioned document : JLS3 "Binary Compatibility" (13.1) states it like this (more precise but less concise) :

Furthermore, the resulting class file must have certain properties. A number of these properties are specifically chosen to support source code transformations that preserve binary compatibility. The required properties are:

The class or interface must be named by its binary name, which must meet the following constraints:

The binary name of a top level type (§7.6) is its canonical name (§6.7).

The binary name of a member type (§8.5, §9.5) consists of the binary name of its immediately enclosing type, followed by $, followed by the simple name of the member.

The binary name of a local class (§14.3) consists of the binary name of its immediately enclosing type, followed by $, followed by a non-empty sequence of digits, followed by the simple name of the local class.

The binary name of an anonymous class (§15.9.5) consists of the binary name of its immediately enclosing type, followed by $, followed by a non-empty sequence of digits.

The binary name of a type variable declared by a generic class or interface (§8.1.2, §9.1.2) is the binary name of its immediately enclosing type, followed by $, followed by the simple name of the type variable.

The binary name of a type variable declared by a generic method (§8.4.4) is the binary name of the type declaring the method, followed by $, followed by the descriptor of the method as defined in The Java™ Virtual Machine Specification, Java SE 7 Edition, followed by $, followed by the simple name of the type variable.

The binary name of a type variable declared by a generic constructor (§8.8.4) is the binary name of the type declaring the constructor, followed by $, followed by the descriptor of the constructor as defined in The Java™ Virtual Machine Specification, Java SE 7 Edition, followed by $, followed by the simple name of the type variable.

So it can be said that the commonly known naming scheme is perfectly normalized and we can rely on it (as must rely all class loaders to find the necessary class files).

Autres conseils

I believe that the naming scheme is not specified in the formal sense because it is (supposedly) an implementation detail.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top