我是Java新手,有些事情我不清楚。 例如,在C ++中,如果我们有
class A {
int field1;
int field2;
void method() { }
} a;
我们使用a.field1
或a.method()
,编译器已经知道它们相对于a
存储在内存中的位置。但Java具有.class文件,这些文件具有关于字段和方法及其名称的信息,因此对于使用这些字段和方法的人而言,将它们存储在内存中的位置并不重要。这是否意味着当我们在Java中a.field1
时,JVM首先计算出该字段必须在内存中相对于a
的位置,然后获取此字段或者将所有a.field1
更改为启动时*(a + offset of field1)
,a.field2
到*(a + offset of field2)
等?
答案 0 :(得分:2)
Java中的情况与C ++中的情况基本相同:JVM知道字段在对象中的位置。
如果你想了解所有血腥细节,你可以在the JVM specification中阅读,特别是getfield
bytecode,其中包括:
objectref ,必须是
reference
类型,从操作数堆栈中弹出。 unsigned indexbyte1 和 indexbyte2 用于构造当前类(§2.6)的运行时常量池的索引,其中索引的值为(indexbyte1<< 8)| indexbyte2 。该索引处的运行时常量池项必须是对字段(第5.1节)的符号引用,该字段提供字段的名称和描述符以及对要在其中找到字段的类的符号引用。引用的字段已解决(第5.4.3.2节)。获取objectref中引用字段的值并将其推送到操作数堆栈。objectref 的类型不能是数组类型。如果该字段是
protected
,并且它是当前类的超类的成员,并且该字段未在与当前类相同的运行时包(第5.3节)中声明,那么< em> objectref 必须是当前类的当前类或子类。