代码编译的结果从本地机器码转变为字节码, 是格式存储的发展的一小步, 却是编程语言发展的一大步 ---- 深入理解JVM
什么是虚拟机的类加载机制?
虚拟机把编译后的 class 字节码加载到内存, 并对其进行效验,解析 和 初始化后, 最终形成可以被虚拟机直接使用的 java 类型. 这个过程便是 类 加载机制.
简单来说, 就是把 class 字节码文件, 转换成我们在 java 程序中使用的一个个 class 对象.
Java 的类型的加载, 连接, 和初始化的过程都是在程序运行期间才开始的, 这虽然会有一定的效率影响, 但这给编程带了极大的灵活性, 比如我们在程序运行期间, 可以从网络上下载二进制字节码文件, 然后将其加载, 变成代码的一部分, 大致觉得 热修复 和这个联系很大.
在 java 中, 只有 类 和 接口 编译后才会产生 class 文件.
Class 对象的完整生命周期:
这七个过程在 类 的加载过程中会 按部就班 的开始, 注意是开始, 不是按部就班的完成, 这几个过程很有可能会同时运行.
虚拟机没有明确规定一个类何时应该被加载, 但是明确规定了, 有且只有 下面五种情况必须马上对类进行初始化, 当然, 之前的过程自然需要在此之前开始:
注意:
当我们使用一个 类 来定义一个数组时, 这个类不会得到加载, 虚拟机会自动的为这个类生成一个 同名加上 ' [ ' 前缀的类来表示这个数组类, 数组中的属性和方法都实现在这个类里面. 这也就表明了 jvm 中, 数组对象是用一个 类 来表示的, 终于可以理解为什么基本类型的数组是引用类型了.
需要注意的地方, 虚拟机中是采用 class 文件和 加载这个 class 文件的类加载器来决定一个类在 一个 虚拟机中的唯一性的.
举个例子, 比如我们使用自定义 类 加载器加载了 类 A , 然后生成了一个实例对象, 当我们使用 instanceof 去和 由系统加载的 类A 的class 对象进行比较时, 会得到 false, 即使采用 class.getName 会得到一模一样的名字, 这一点需要注意.