【问题标题】:What happens when java program starts?java程序启动时会发生什么?
【发布时间】:2012-12-05 07:40:15
【问题描述】:
【问题讨论】:
标签:
java
jar
jvm
classloader
executable-jar
【解决方案1】:
•谁以及如何决定在启动时应该加载哪些类以及需要哪些类?
我们需要了解 java 类加载的基础知识。最初,引导类加载器(它作为 VM 本身的一部分本地实现)负责加载核心系统类。然后还有其他类加载器,如扩展、系统、用户定义(可选)类加载器,它们决定何时以及如何加载类。
Fundamentals of class loading
【解决方案2】:
由类加载器做出决定。有不同的实现,其中一些预加载它们可以加载的所有类,而另一些则仅在需要时加载类。
一个类只有在第一次从程序代码中访问时需要被加载;这种访问可能是该类中对象的实例化,也可能是对其static 成员之一的访问。通常,默认的类加载器会在需要时延迟加载类。
在任何情况下都不能依赖某些类进行预加载:在实际执行此代码之前,可能无法确定通过 Class.forName(...) 访问的类。
在其他选项中,对于简单的实验,您可以使用静态初始化程序代码来查看实际加载类的实际时间和顺序;该代码将在第一次加载类时执行;示例:
class SomeClass {
static {
System.out.println("Class SomeClass was initialized.");
}
public SomeClass() {
...
}
...
}
【解决方案3】:
您的示例显示了一个可执行 jar,它只是一个普通的 java 存档 (jar),其清单文件(位于文件夹 "META_INF")中有一个额外的键/值对。键是“Main-Class”,值是该类的完全限定类名,如果您像示例中一样“运行”jar,则该类的“main”方法将被执行。
jar 是一个 zip 文件,您可以使用每个 zip 存档工具查看内部文件。
【解决方案4】:
每当您编译 Java 程序时,都会执行以下步骤
- 首先,类加载器将类加载到 JVM 中。
- 在给出命令 javac filename.java 后,编译器会检查编译时错误,如果一切正常,它将生成 .Class 文件(字节码)。
这将是第一阶段。
稍后解释器检查运行时错误,如果一切正常且无异常,则解释器将字节码转换为可执行代码。
Java 的第一阶段由 JIT 编译器完成(Just In Time)。