[Java] JVM 在执行 main 方法前的行为
JVM 执行一个 Java 程序时,先从某个指定的 Java 类的 main 方法开始执行代码,同时,传一个字符串数组作为 main 方法的参数。例如在 Unix 系统上,执行下面的命令
java Test reboot Bob Dot Endzo
JVM 会调用 Test 的 main 方法,同时把四个字符串 "reboot", "Bob", "Dot" "Endzo" 作为参数传给 main 方法。
那么,在执行 main 方法前,JVM 需要做什么事情呢?本文将简单地回答这个问题。
JVM 启动调用 main 方法,一共经过四个阶段:加载( Load )、链接( Linkage )、初始化( Initialization )、调用( Invocation )
加载一个类 Test
在最开始,JVM 里面是没有 Test 类的,准确地说,是没有 Test 类的二进制表代码,需要先加载 Test 。JVM 使用类加载器( class loader ) 去搜索 Test 的二进制代码,然后加载。如果类加载器搜索不到,则抛出异常。
链接一个类 Test
在 JVM 里面包含了 Test 类的二进制代码后,需要通过链接动作,将 Test 的二进制形式连接到 JVM 的运行时状态,然后才可以执行 Test 二进制代码。链接包含三个动作:验证( Verify ),准备( Prepare ),解析(Resolve),其中解析行为是可选的。
验证:检查加载完的 Test 类二进制代码格式是否正确,语义是否符合 Java 语言规范、JVM 规范。
准备:分配静态存储空间,以及任何 JVM 所需要的数据结构,例如方法列表( method table )
解析:检查 Test 类引用的类或接口,加载所引用的其他类或接口,并检查他们是否正确。
初始化一个类 Test
初始化包括静态变量的初始化,和静态代码块的初始化。初始化是按文本顺序进行。如果 Test 类可以被初始化,其直接父类需要先被初始化了,而如果直接父类可以被初始化,直接父类的直接父类需要先被初始化了,以此递推。Object 类没有父类,所以 Object 类初始化后,递推结束。
在初始化直接父类的时候,如果直接父类还没有被加载,则需要先加载、链接、初始化直接父类。所以,在初始化一个类阶段,有可能会抛出加载错误、链接错误、初始化错误。
调用 Test.main
当前面的加载、链接、初始化都正常结束后,JVM 会调用 Test 的 main 方法。被调用的 main 必须被修饰为 public , static, void 。可接受的形式有两种:
public staitc void mian(String[] args)
public staitc void main(String... args)
参考资料
12.1 Java Virtual Machine Startup, The Java Language Specification, Java SE 8 Edition
[Java] JVM 在执行 main 方法前的行为的更多相关文章
- 第2篇-JVM虚拟机这样来调用Java主类的main()方法
在前一篇 第1篇-关于JVM运行时,开篇说的简单些 中介绍了call_static().call_virtual()等函数的作用,这些函数会调用JavaCalls::call()函数.我们看Java类 ...
- 第4篇-JVM终于开始调用Java主类的main()方法啦
在前一篇 第3篇-CallStub新栈帧的创建 中我们介绍了generate_call_stub()函数的部分实现,完成了向CallStub栈帧中压入参数的操作,此时的状态如下图所示. 继续看gene ...
- Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
- 【异常】idea执行Main方法出现 Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
一.异常复现步骤 1)首先得是一个Spring MVC项目 注:Spring Boot项目有内置的web 容器,不会出现该问题 2)main方法存在于使用HttpServletRequest类的类中 ...
- Java程序入口:main()方法讲解
Java程序的入口---main()方法的签名为:public static void main(String[] args) {...} ,其中, ♦ public修饰符:Java类由JVM调用,为 ...
- 第29篇-调用Java主类的main()方法
在第1篇中大概介绍过Java中主类方法main()的调用过程,这一篇介绍的详细一点,大概的调用过程如下图所示. 其中浅红色的函数由主线程执行,而另外的浅绿色部分由另外一个线程执行,这个线程最终也会负责 ...
- 反射中的一个问题点:利用Method执行main方法特殊的地方
利用Method执行main方法 问题: 启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个m ...
- java语言规范,main方法必须声明为public
注释: 根据java语言规范,main方法必须声明为public. 当main方法不是public时,有些版本的java解释器也可以执行java应用程序.有个程序员报告了这个bug. 如果感兴趣可以查 ...
- Ideal test 不执行main方法了
参考:idea 导入项目后不能执行main方法 用了ideal之后,发现自己的项目里面没有test文件夹,自己建了一个,发现竟然不能执行main函数, 后来经过点播之后,才知道,光建立文件夹是没用的, ...
随机推荐
- 今日推荐(三)AndroidResideMenu类似QQ侧滑效果
效果图: DEMO 本代码即是DEMO,您可以下载后选择您喜欢的IDE运行.SDK版本建议使用4.0以上 Version Migration 从 v1.0, v1.1, v1.2, v1.3 升级到 ...
- python手机号码运营商归属测试
#手机号码测试: def number_test(): while True: number = input('Please enter your phone number:') CN_mobile ...
- VS2008 快捷键大全--------<<转>>
VS2008 快捷键大全 Ctrl+E,D ---- 格式化全部代码 Ctrl+K,F ---- 格式化选中的代码 CTRL + SHIFT + B ...
- jQuery的选择器中的通配符[id^='code']或[name^='code']
这两天在做一个专题的时候遇到了一个通配符的问题 //弹层操作$(function(){ //视频播放 $("a[href^='#video']").each(function(in ...
- JavaScript设计模式之观察者模式(学习笔记)
设计模式(Design Pattern)对于软件开发来说其重要性不言而喻,代码可复用.可维护.可扩展一直都是软件工程中的追求!对于我一个学javascript的人来说,理解设计模式似乎有些困难,对仅切 ...
- Char Varchar Nvarchar区别
char和varchar是一样的字符型,不同在于,varchar比char更灵活,精确,且不占内存空间,当你取同样的字符时,char会在该字符后面加上空格,而varchar则只取得这个字符,比如有字段 ...
- TalkingDataGame SDK在android Lua上的使用
千呼万唤使出来...终于开始更新lua版本的内容了,之前一直有这方面的计划,由于公司业务比较多,一直比较忙-见谅.. 费话不多说,直接上内容.. 整体来讲,先是先建议看一下之前关于cocos2dx上的 ...
- Android源码下载方法详解
转自:http://www.cnblogs.com/anakin/archive/2011/12/20/2295276.html Android源码下载方法详解 相信很多下载过内核的人都对这个很熟悉 ...
- mysql 字符串拼接函数CANCAT()与GROUP_CANCAT()
1.CONCAT() 拼接单行字符串 select concat(‘100’,user_id) from table1; select concat('11','22','33'); 结果 11223 ...
- 如何把powerpoint幻灯片大小改为标准或宽屏教程【图文】
不知道大家还记得早期powerpoint版本,幻灯片的形状是较方(4:3),随着科技的发展,很多电视.视频都在用宽屏,powerpoint自然也是如此,现在默认的幻灯片大小是宽屏 (16:9),怎么把 ...