Java 类的加载、连接、初始化详解

当程序主动调用某个类时,如果这个类还未被加载到内存,系统会通过加载、连接、初始化三个步骤对这个类进行初始化。在这之前,我们先讲下类编译的概念:

编译

java类的编译是将.java文件转化为.class二进制文件,使用javac test.java就可编译成test.class文件。

加载

java类的加载是将class文件通过类加载器加载到内存中,并且为之生成Class对象,也就是说当程序被加载到内存时,系统都会为之建立一个Class对象。所有类都是java.lang.Class的实例。
类的加载通常由类加载器完成,类加载器通常由jvm提供,这些类加载器也是我们前面所有程序运行的基础,jvm提供的这些类加载器通常被称为系统类加载器。

连接

java类的连接是将二进制class数据合并到JRE中,类的连接又分为三个阶段

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

初始化

在类的初始化阶段,虚拟机负责对类进行初始化,主要是对静态属性进行初始化。在java类中对静态属性指定初始值有两种方式:

  • 1.声明静态属性时指定初始值
  • 2.使用静态初始化块为静态属性指定初始值。
类初始化的时机
  • 创建类的实例。为某个类创建实例的方式包括使用new操作符来创建实例,通过反射来创建实例,通过反序列化的方式来创建实例。
  • 调用某个类的静态方法。
  • 访问某个类或接口的静态属性,或为该静态属性赋值。
  • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。
  • 初始化某个类的子类,当初始化某个类的子类时,该子类的所有父类都会被初始化。
  • 直接使用java.exe命令来运行某个主类,当运行某个主类时程序会先初始化这个主类。
    除此之外,下面有几种情形需要特别指出:
    对于一个final型的静态属性,如果该属性可以在编译时就得到属性值,则可认为该属性可被当成编译时的常量。当程序使用编译时常量时,系统会认为这是对该类的被动使用,所以不会导致该类的初始化。反之,如果final类型的静态属性的值不能在编译时得到,必须等到运行时才可以确定该属性的值,如果通过该类来访问该静态属性,则可以认为是主动访问使用该类,将会导致类被初始化。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,308评论 19 139
  • 1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,...
    java小菜鸟阅读 7,385评论 0 15
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,898评论 18 399
  • 全目录 上一章 杨云海走后,乔文瘫坐在沙发里动都不想动,想想这一天的遭遇心情降到冰点。她看着自己打着石膏的手,僵硬...
    林秋千阅读 3,294评论 0 4
  • 岳父得到了我答应凑钱买房的承诺,心情大好,在这边住了几天后,就带着袁靖回了深圳,说是准备准备,可能下个月就会到上海...
    张孤山阅读 1,651评论 0 0