Search code examples
jvmclassloaderinner-classes

How jvm classloader loads class that is defined inside another class?


How does JVM loads class that are defined inside another class?

Example: Lets say, there is a class B that is defined inside class A

package test.sample;
    Class A {
         // some instructions

         Class B {
             // few more instructions
         }
    }

In this case,

  1. How does classloader load the class B? (i.e., How does it identify class B?)
  2. What will be the fully qualified name of class B?

Solution

  • Inner classes are a Java language feature, not a JVM feature. That is, Java compilers "flatten" the class structure, so the JVM just sees regular classes, usually with $ in their names. In this case, there would be classes test.sample.A and test.sample.A$B (the latter being the fully qualified name of B). Anonymous inner classes get compiler-defined names, typically starting at 1 and counting up: test.sample.A$6, for example. The compiler may add methods with names like access$200 to allow the enclosing class and inner class to access each others' private members. (Note that $ is legal, though discouraged, in user-defined class and method names, so the presence of a $ in a name does not mean it is compiler-generated; for that, there's the Synthetic attribute and ACC_SYNTHETIC modifier bit, exposed reflectively via methods like Class.isSynthetic().)

    The JVM loads these classes just like any other class, typically looking for a file test/sample/A$B.class in some JAR file, but also possibly loading them across a network, generating them on-the-fly with a bytecode manipulation library, etc.

    When generating class files that reference an inner class (defining, containing, or simply using), Java compilers emit InnerClasses attributes specifying the containment relationships, for the aid of separate compilation and reflection (Class.getDeclaringClass() and Class.getEnclosingClass()). Class files for classes defined inside a method also contain an EnclosingMethod attribute referring to the enclosing method, for reflection (Class.getEnclosingMethod() and Class.getEnclosingConstructor()). However, these attributes are only checked for syntactic well-formedness by the JVM during loading and linking; inconsistencies are not reported until the reflective methods are actually called.