• 类的加载和初始化 ---- new 一个对象时,在JVM 中的过程是什么


    在程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三个步骤来对该类进行初始化。如果没有意外,JVM 将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或类初始化。

    类的加载

    类加载指的是将类的 class 文件读入内存,并为之创建一个 java.lang.Class 对象,也就是说,当程序中使用任何类时,系统都会为之建立一个 java.lang.Class 对象。

    类的加载由类加载器完成,类加载器通常由 JVM 提供,这些类加载器负责将 .class 文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成一个 java.lang.Class 对象。

    类的连接

    当类被加载之后,系统为之生成一个对应的 Class 对象,接着将会进入连接阶段,连接阶段负责把类的二进制数据合并到 JRE 中。

    类的连接又可分为如下三个阶段:

    1. 验证:这阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。
    2. 准备:类准备阶段负责为类变量分配内存,并设置默认初始值。
    3. 解析:将类的二进制数据中的符号引用替换成直接引用。

    类的初始化

    在类的初始化阶段,虚拟机负责对类进行初始化,主要就是对类变量进行初始化。对类变量指定初始值有两种方式:

    1. 声明类变量时指定初始值;
    2. 使用静态代码块为类变量指定初始值。

    小总结

    JVM 初始化一个类包含如下几个步骤:

    1. 假如这个类还没有被加载和连接,则程序先加载并连接该类。
    2. 假如该类的直接父类还没有被初始化,则先初始化其直接父类。
    3. 假如类中有初始化语句,则系统依次执行这些初始化语句。

    当执行第 2 个步骤时,系统对直接父类的初始化步骤也是遵循 1~3 步骤;如果改直接父类又有直接父类,系统再次重复这三个步骤来初始化这个父类......以此类推,所以 JVM 最先初始化的总是 java.lang.Object 类。这个策略也称之为双亲委派策略

    类初始化的时机

    当 Java 程序首次通过下面 6 种方式来使用某个类或接口时,系统就会初始化该类和接口。

    • 创建类的实例。包括:使用 new 来创建实例;通过反射来创建实例,通过反序列化的方式来创建实例。
    • 调用某个类的类方法(静态方法)
    • 访问某个类或接口的类变量,或为该类变量赋值
    • 使用反射来强制创建某个类或接口对应的 java.lang.Class 对象
    • 初始化某个类的之类。初始化某个类的子类时,该子类的所有父类都会被初始化。
    • 直接使用 java.exe 命令来运行某个主类。当运行某个主类时,程序会先初始化该主类。

    【特别注意】

    对于一个 final 型的类变量,如果该类变量的值在编译时就能确定下来,这个类变量就是 “宏变量”,Java 编译器会直接这个类变量出现的地方直接替换成它的值(相当于使用了常量)。因此程序在使用该静态类变量时,并不会导致该类的初始化。

  • 相关阅读:
    抗变与协变
    border-width实现博客园回复效果
    福利到!分享我的分页控件
    linq distinct 不够用了!
    sql server 使用nolock提升性能
    Graph-Based image segmentation method
    纹理特征提取【转】
    ROC曲线【转】
    LBP纹理特征[转自]
    SPAMS:稀疏建模工具箱
  • 原文地址:https://www.cnblogs.com/luler/p/15242195.html
Copyright © 2020-2023  润新知