要运行一个 main 方法 , 首先要知道 main 方法所在的 Class, 在命令行中指定这个 Class 名
Class Lava{
Private int speed = 4;
Void flow(){
}
}
Class Volcano{
Public static void main(String[] args){
Lava lava = new Lava();
lava.flow();
}
}
Java Lava
1. 当虚拟机接受到这样的命令后 , 就从 class 文件 (Volcano.class) 中提取类型信息放到方法区中
2. 执行这个类字节码 , 即执行 main() 方法 . 在执行时会一直指向当前类的常量池的指针
3. main() 方法的第一条指令告知虚拟机为列在常量池第一项的类分配足够的内存
4. 第一项是 Lava 的符号引用 , 然后去装载这个 class 文件到方法区 , 然后把第一项的符号引用改成一个指针 , 这个指针指向方法区中 Lava 类数据 . 以后就可以快速的用指针访问了 .
5. 实例化 Lava 时 , 为 Lava 分配内存 . 这个内存的大小是通过存储在方法区中的类型信息中获得的
6. 把新生的 Lava 对象压到栈中 ,main() 方法的第一条指令就完成了
为什么必须要求 : 通过对象能够找到他的类型信息呢 :
答 >>1. 当一种类型转化成另一种类型时 , 虚拟机要检查能否进行转换 , 如
List list = new ArrayList();
虚拟机怎么知道 ArrayList 能够转换成 List 类型呢 ? 只能去方法区中查看类型信息 .
2.instanceof 也是如此
3. 当程序调用实例的方法时 , 虚拟机必须进行动态绑定 . 换句话说 , 不能按照引用的类型来决定调用的方法 , 必须根据对象实际的类型进行调用 . 举例如下 :
List list = new ArrayList();
list.size();
执行 size() 方法时 . 是执行 List 类型的 size() 呢还是 ArrayList 的 size() 呢 ? 虚拟机就去找类型信息 , 再决定执行哪个 .
上面只是举例 , 当然 List 是接口是不能执行的 .
关于对象的方法表 :
不管虚拟机的实现使用什么样的对象表示方法 , 一般的对象都有一个方法表 , 方法表可以加快调用实例方法时的效率 ----- 很快可以找到要执行的代码
http://www.blogjava.net/esoa/articles/89400.html