Java代码到底是如何运行起来的?
程序运行的两种形式:
1、通过采用jar包的形式
2、war包---->tomcat
1个Java文件从编码完成到最终执行,一般主要包括两个过程:
1、编译
2、运行
编译
1、写好代码后,会通过编译器将代码编成.class后缀的字节码文件。
2、Java是与平台无关的,一次编写到处运行,实现语言无关性的基础就是虚拟机和字节码存储格式。
3、只要编译器按照虚拟机规范,编译成对应的 .clsss 文件,这个.class文件就能被JVM加载。不同的操作系统通过对应的版本载入这个.classs文件,则实现饿平台无关性。
运行
运行,则是把编译声称的.class文件交给Java虚拟机(JVM)执行。
而我们所说的类加载过程即是指JVM虚拟机把.class文件中类信息加载进内存,并进行解析生成对应的class对象的过程。
类加载
1、JVM要运行这些.class字节码文件中年的代码,那就把.class文件中的各种类给加载进来,这就涉及到类加载的过程。
2、通过类加载器,可以把编译好的.class字节码文件给加载到JVM中。
类加载的过程主要分为三个部分:
-
加载
-
链接
-
初始化
加载
简单来说,加载指的是把class字节码文件从各个来源通过类加载器装载入内存中。
这里有两个重点:
1、字节码来源。一般的加载来源包括从本地路径下编译生成的.class文件,从jar包中的.class文件,从远程网络,以及动态代理实时编译
2、类加载器。一般包括启动类加载器,扩展类加载器,应用类加载器,以及用户的自定义类加载器。
注:为什么会有自定义类加载器?
1、一方面是由于java代码很容易被反编译,如果需要对自己的代码加密的话,可以对编译后的代码进行加密,然后再通过实现自己的自定义类加载器进行解密,最后再加载。
2、另一方面也有可能从非标准的来源加载代码,比如从网络来源,那就需要自己实现一个类加载器,从指定源进行加载。
而链接又可以细分为三个小部分:
-
验证
-
准备
-
解析
链接
在类被加载后,需通过链接过程将它合并到JVM的运行状态之中,然后才可以执行。链接过程分三个步骤。
1、验证
假设.class文件本人篡改了,不符合JVM的规范,那么JVM是没法去执行的。
2、准备
准备工程中,给内部的类变量分配内存空间并设置默认的初始值。准备并不会执行具体的代码。
int 变量设置默认初始值为0
3、解析
确保这些被引用的类被正确找到,这个过程可能会导致其他的java类被加载进来。
初始化
在链接完成之后,会对类初始化的过程,初始化的过程主要操作的是静态代码快和静态变量。
需要注意的点:
1、一个类被初始化之前,它的直接父类也需要被初始化。
2、一个接口的初始化不会引起其父接口的初始化。
总结
首先从Idea中编写代码,然后通过编译器将代码转化为.class(字节码)文件。这个字节码文件必须是遵循JVM规范的。编译后通过类加载到JVM中。然后执行链接过程:验证、准备和解析。链接阶段完成之后进行初始化操作,对静态代码块和静态变量进行初始化。