java的类文件中存在private类吗

举个简单的例子:
public class OuterClass { private class InnerClass { }}javac编译后这个在Java语法层面上拥有一个内部私有类InnerClass的OuterClass,其实是生成了两个具有嵌套关系的class文件:
OuterClass.class,javap -v -p OuterClass.class(省略了部分内容):
public class OuterClass minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER{ public OuterClass(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."\u0026lt;init\u0026gt;":()V 4: return LineNumberTable: line 6: 0 line 7: 4 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LOuterClass;}SourceFile: "OuterClass.java"InnerClasses: private #12= #11 of #9; //InnerClass=class OuterClass$InnerClass of class OuterClassOuterClass$InnerClass.class,javap -v -p后形式如下(省略了部分内容):
class OuterClass$InnerClass minor version: 0 major version: 52 flags: ACC_SUPER{ final OuterClass this$0; descriptor: LOuterClass; flags: ACC_FINAL, ACC_SYNTHETIC private OuterClass$InnerClass(OuterClass); descriptor: (LOuterClass;)V flags: ACC_PRIVATE Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:LOuterClass; 5: aload_0 6: invokespecial #2 // Method java/lang/Object."\u0026lt;init\u0026gt;":()V 9: return LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 10 0 this LOuterClass$InnerClass;}SourceFile: "OuterClass.java"InnerClasses: private #13= #3 of #20; //InnerClass=class OuterClass$InnerClass of class OuterClass 【java的类文件中存在private类吗】 对于类OuterClass$InnerClass的ACC_FLAG是默认ACC_SUPER,但是我们注意到class文件最后的InnerClasses属性(关于InnerClasses Attribute,参见:Chapter 4. The class File Format),在后续字节码解析过程中,JVM会根据这个属性集合来对嵌套类的访问修饰符号重新计算:
jint InstanceKlass::compute_modifier_flags(TRAPS) const { jint access = access_flags().as_int(); // But check if it happens to be member class. instanceKlassHandle ik(THREAD, this); InnerClassesIterator iter(ik); for (; !iter.done(); iter.next()) { int ioff = iter.inner_class_info_index(); // Inner class attribute can be zero, skip it. // Strange but true: JVM spec. allows null inner class refs. if (ioff == 0) continue; // only look at classes that are already loaded // since we are looking for the flags for our self. Symbol* inner_name = ik-\u0026gt;constants()-\u0026gt;klass_name_at(ioff); if ((ik-\u0026gt;name() == inner_name)) { // This is really a member class. access = iter.inner_access_flags(); break; } } // Remember to strip ACC_SUPER bit return (access \u0026amp; (~JVM_ACC_SUPER)) \u0026amp; JVM_ACC_WRITTEN_FLAGS;}


推荐阅读