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 方法前的行为的更多相关文章

  1. 第2篇-JVM虚拟机这样来调用Java主类的main()方法

    在前一篇 第1篇-关于JVM运行时,开篇说的简单些 中介绍了call_static().call_virtual()等函数的作用,这些函数会调用JavaCalls::call()函数.我们看Java类 ...

  2. 第4篇-JVM终于开始调用Java主类的main()方法啦

    在前一篇 第3篇-CallStub新栈帧的创建 中我们介绍了generate_call_stub()函数的部分实现,完成了向CallStub栈帧中压入参数的操作,此时的状态如下图所示. 继续看gene ...

  3. Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  4. 【异常】idea执行Main方法出现 Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest

    一.异常复现步骤 1)首先得是一个Spring MVC项目 注:Spring Boot项目有内置的web 容器,不会出现该问题 2)main方法存在于使用HttpServletRequest类的类中 ...

  5. Java程序入口:main()方法讲解

    Java程序的入口---main()方法的签名为:public static void main(String[] args) {...} ,其中, ♦ public修饰符:Java类由JVM调用,为 ...

  6. 第29篇-调用Java主类的main()方法

    在第1篇中大概介绍过Java中主类方法main()的调用过程,这一篇介绍的详细一点,大概的调用过程如下图所示. 其中浅红色的函数由主线程执行,而另外的浅绿色部分由另外一个线程执行,这个线程最终也会负责 ...

  7. 反射中的一个问题点:利用Method执行main方法特殊的地方

    利用Method执行main方法 问题: 启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个m ...

  8. java语言规范,main方法必须声明为public

    注释: 根据java语言规范,main方法必须声明为public. 当main方法不是public时,有些版本的java解释器也可以执行java应用程序.有个程序员报告了这个bug. 如果感兴趣可以查 ...

  9. Ideal test 不执行main方法了

    参考:idea 导入项目后不能执行main方法 用了ideal之后,发现自己的项目里面没有test文件夹,自己建了一个,发现竟然不能执行main函数, 后来经过点播之后,才知道,光建立文件夹是没用的, ...

随机推荐

  1. 解决下载android sdk慢的问题

    修改host文件 203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.com 强制不使用https访问 在sdk manager里选择t ...

  2. Android ViewPager 打造炫酷欢迎页

    Android ViewPager 打造炫酷欢迎页 ViewPager是Android扩展v4包中的类,这个类可以让用户切换当前的View.对于这个类的应用场景,稍加修改就可以应用到多个环境下.比如: ...

  3. win7/win8 64位系统注册TeeChart8.ocx 控件---以及dllregisterserver调用失败问题解决办法

    TeeChart控件就不多介绍了,很多朋友不知道开始怎么注册使用,尤其是在64位系统下如何注册的问题,具体如下: win7.win8  64位系统问题所在: 64位的系统一般都是可以安装32位程序的 ...

  4. (转)Div左右两侧等高

    一. 利用背景图,做出左右等高的模拟效果   这种方法不是真正的左右等高,而是在外框元素中添加一张背景图片,当内容增多时,背景会纵向重复,就会形成左右等高的效果. 这种方法不是真正的div自动等高,而 ...

  5. css3中-webkit-text-size-adjust详解

    1.当样式表里font-size<12px时,中文版chrome浏览器里字体显示仍为12px,这时可以用 html{-webkit-text-size-adjust:none;} 2.-webk ...

  6. 数据类型的转换String

    x.toString(): 无法转换null和undefined 不过String()却是万能的,其中的原理如下 function String(x){ if(x===undefined){ retu ...

  7. [Ext JS 4] 实战之Grid, Tree Gird 添加按钮列

    引言 贴一个grid 的例子先: 有这样一个需求: 1. 给 Grid(or Tree Grid)添加一列, 这一列显示是Button. 点击之后可以对这一行进行一些操作 2. 这一列每一行对应的按钮 ...

  8. Python django admin 替换表单控件

    测试版本: Python 2.7 Django 1.6.2 models.py from django.db import models class Article(models.Model): ti ...

  9. 你真的了解console吗?

    对于前端开发者来说,在开发过程中需要监控某些表达式或变量的值的时候,用 debugger 会显得过于笨重,取而代之则是会将值输出到控制台上方便调试.最常用的语句就是console.log(expres ...

  10. underscorejs-groupBy学习

    2.18 groupBy 2.18.1 语法 _.groupBy(list, iteratee, [context]) 2.18.2 说明 把list分为多个集合,iterator为分组的依据,返回值 ...