由于 JVM 规范,class
文件是这样构建的:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
该super_class
领域包括:
`对于一个类,super_class 项的值要么必须为零,要么必须是 constant_pool 表的有效索引。如果 super_class 项的值非零,则该索引处的 constant_pool 条目必须是一个 CONSTANT_Class_info (§4.4.1) 结构,表示该类文件定义的类的直接超类。直接超类及其任何超类都不能在其 ClassFile 结构的 access_flags 项中设置 ACC_FINAL 标志。
如果 super_class 项的值为零,则该类文件必须表示类 Object,即唯一没有直接超类的类或接口。
对于接口,super_class 项的值必须始终是 constant_pool 表的有效索引。该索引处的 constant_pool 条目必须是表示类 Object 的 CONSTANT_Class_info 结构。
更有趣的是fields[]
部分:
Each value in the fields table must be a field_info (§4.5) structure giving a complete description of a field in this class or interface. The fields table includes only those fields that are declared by this class or interface. It does not include items representing fields that are inherited from superclasses or superinterfaces.
所以编译的类不包含继承的字段。另一方面,当创建对象时,private
超级字段在内存中。为什么?让我们想象一下这个例子:
classs A {
int a;
A(int a) {
this.a = a;
}
void methodA() {
System.out.println("A is: " + a);
}
}
classs B extends A {
int b;
B(int b) {
super(10);
this.b = b;
}
void methodB() {
super.methodA();
System.out.println("B is: " + b);
}
}
输出应该是:A is: 10 \n B is ...
。