JVM如何加载在另一个类中定义的类?
示例:假设有一个在A类中定义的B类
package test.sample;
Class A {
// some instructions
Class B {
// few more instructions
}
}
在这种情况下,
答案 0 :(得分:1)
内部类是Java语言功能,而不是JVM功能。也就是说,Java编译器" flatten"类结构,因此JVM只能看到常规类,通常名称中包含$
。在这种情况下,会有类test.sample.A
和test.sample.A$B
(后者是B
的完全限定名称)。匿名内部类获得编译器定义的名称,例如,通常从1
开始并向上计数:test.sample.A$6
。编译器可以添加名称为access$200
的方法,以允许封闭类和内部类相互访问'私人会员。 (请注意,$
在用户定义的类和方法名称中是合法的,但是不鼓励,因此名称中$
的存在并不意味着它是由编译器生成的;为此,有&# 39; s Synthetic attribute和ACC_SYNTHETIC修饰符位,通过Class.isSynthetic()等方法反射出来。)
JVM像任何其他类一样加载这些类,通常在某些JAR文件中查找文件test/sample/A$B.class
,但也可能在网络中加载它们,使用字节码操作库即时生成它们等等。
当生成引用内部类(defining, containing, or simply using)的类文件时,Java编译器会发出指定包含关系的InnerClasses属性,以帮助单独编译和反射(Class.getDeclaringClass() and Class.getEnclosingClass())。方法内定义的类的类文件还包含一个EnclosingMethod属性,引用封闭方法,用于反射(Class.getEnclosingMethod()和Class.getEnclosingConstructor())。但是,这些属性仅在加载和链接期间由JVM检查语法的良好格式;在实际调用反射方法之前,不会报告不一致性。