类的初始化详细过程

字节码-->加载-->验证-->准备-->解析-->初始化

1)加载:通过类的完全限定名找到类文件所在位置,根据其中的字节码创建java.lang.Class对象,所以才会说万物皆对象,我们也可以继承ClassLoader,重写findClass方法来自定义实现类加载器。默认情况下我们都使用AppClassLoader。

1.通过全类名获取定义此类的二进制字节流

2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构

3.在内存中(对于HotSpot虚拟就而言就是方法区)生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

2)验证:确保加载的字节码的是否符合虚拟机的要求,是java提供的一种自我保护机制,不让其危害虚拟机安全。其主要包括四种验证,字节码验证、文件格式验证,元数据验证、符号引用验证

3)准备为类变量分配地址和初始化值,类变量会分配到方法区(元空间)中,这里的初始化是指该数据类型的默认初始值,例如int对应的是0,long对应的0L,只有在初始化时才会动显示赋值。实例变量主要随着对象的实例化一块分配到java堆中

4)解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。

--符号引用(在编译时java类并不知道引用类的实际内存地址,因此使用符号引用来代替)就是一组符号来描述目标,可以是任何字面量(理解为自然语言,只需要能无歧义的定位到指示的目标即可)。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。在程序实际运行时,只有符号引用是不够的,举个例子:在程序执行方法时,系统需要明确知道这个方法所在的位置。Java虚拟机为每个类都准备了一张方法表来存放类中所有的方法。当需要调用一个类的方法的时候,只要知道这个方法在方发表中的偏移量就可以直接调用该方法了。通过解析操作符号引用就可以直接转变为目标方法在类中方法表的位置,从而使得方法可以被调用。

综上,解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,也就是得到类或者字段、方法在内存中的指针或者偏移量

5)初始化:主要为类的静态变量赋予正确的值,比如int num = 10; 这里num的值会从准备阶段的0变为10;并且若该类有父类,会对其进行初始化操作;如果类中有初始化语句,系统会按照顺序进行初始化。

初始化是类加载的最后一步,也是真正执行类中定义的Java程序代码(字节码),初始化阶段是执行类构造器clinit()方法的过程。

初始化过程如下:

类加载器的顺序

Java语言系统自带有三个类加载器:

  1. Bootstrap ClassLoader:最顶层的加载类,主要加载核心类库,也就是我们环境变量下面%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java -Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。
  2. Extention ClassLoader扩展的类加载器,加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件。还可以加载-D java.ext.dirs选项指定的目录。
  3. Appclass Loader也称为SystemAppClass。 加载当前应用的classpath的所有类。

应用程序都是由这三种类加载器互相配合进行加载的,如果有必要,还可以加入自定义的类加载器

Bootstrap ClassLoader > Extention ClassLoader > Appclass Loader

双亲委派机制

当一个类收到了加载请求时,它是不会先自己去尝试加载的,而是委派给父类去完成,比如我现在要new一个 Person,这个 Person 是我们自定义的类,如果我们要加载它,就会先委派 App ClassLoader ,只有当父类加载器都反馈自己无法完成这个请求(也就是父类加载器都没有找到加载所需的 Class)时,子类加载器才会自行尝试加载。

这样做的好处是,加载位于rt.jar包中的类时不管是哪个加载器加载,最终都会委托到BootStrap ClassLoader进行加载,这样保证了使用不同的类加载器得到的都是同一个结果。

其实这个也是一个隔离的作用,避免了我们的代码影响了JDK的代码,比如我现在自己定义一个java.lang.String

尝试运行当前类的 main 函数的时候,我们的代码肯定会报错。这是因为在加载的时候其实是找到了 rt.jar 中的java.lang.String,然而发现这个里面并没有 main 方法。

Java 类的初始化相关推荐

  1. java类成员初始化_简单了解Java类成员初始化顺序

    这篇文章主要介绍了简单了解Java类成员初始化顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 类中包含7中成员: 1.静态变量 static 2 ...

  2. Java类的初始化、变量的初始化

    Java类的初始化.变量的初始化 知识点 Java常量,   final 修饰,值被设定后不能再被修改 静态变量里,  static 修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储 ...

  3. Java 类的初始化顺序

    Java 类的初始化顺序 Java中类的初始化顺序是:父类静态代码块-->子类静态代码块-->父类非静态代码块-->父类构造器-->子类非静态代码块-->子类构造器. 测 ...

  4. java类内容初始化顺序

    在java类中一般有:成员变量.静态变量.成员方法.静态方法.构造方法.那么这几个的初始化顺序是什么呢? 初始化的先后顺序是:静态变量(类load进内存就初始化)------静态代码块(类load进内 ...

  5. Java类的初始化顺序

    对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器. 初始化顺序图示: 我们也可以通过下面的测试代码来验证这一 ...

  6. android 初始化类,Android 常用编程技巧/Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造器)...

    1.设置屏幕的亮度: WindowManager.LayoutParams lp=getWindow().getAttributes(); lp.screenBrightness=1.0f; getW ...

  7. Java类的初始化顺序 (静态变量、静态初始化块、变量、初始...

    很有意思的一篇文章 1.没有继承 静态变量->静态初始化块->变量->变量初始化块->构造方法 2.有继承的情况 父类静态变量->父类静态初始化块->子类静态变量- ...

  8. java类静态初始化_Java静态代码块和类初始化、实例初始化过程

    1. 静态代码块 静态代码块:定义在类中方法外,使用static修饰 ①可以为类变量(静态变量)初始化 ②静态代码块在第一次使用这个类之前执行,即在类初始化时执行,且只执行一次 ③若有多个静态代码块, ...

  9. java类的初始化方法_JAVA类初始化和实例初始化

    一.类初始化过程 1.一个类要创建实例需要先创建和加载 (1) main方法所在的类需要先加载和实例化 2.一个子类要初始化,需要先初始化父类 3.一个类初始化就是执行方法 (1) () 方法由静态类 ...

最新文章

  1. Java集合HashSet
  2. php留言板实现留言评价,PHP实现留言板功能的思路
  3. windows查看端口号占用
  4. AndroidStudio_安卓原生开发_自定义蒙板弹出框WaitDialog---Android原生开发工作笔记134
  5. 解决dev控件版本过期问题
  6. 关于邮件服务器应用系统安全SSL ×××(强身份认证)方案
  7. matlab 例题sin,matlab基础练习题(带答案).doc
  8. 双浮点运算计算机在线,双浮点运算计算器
  9. 数据仓库Hive编程——数据类型和文件格式(三):文本文件数据编码
  10. CF364D Ghd(随机化)
  11. python3 字典_Python3字典
  12. 计算机网络连接图标在哪,电脑网络连接图标不见了
  13. eclipse代码文件误删恢复方法
  14. android用bmob实现评论,Bmob在Android上的应用
  15. Android手机听筒和扬声器切换
  16. python计算选手最后得分_哪位大侠帮我做做这些题目啊要用python的哦,跪求啊 做5个就成...
  17. 前端手把手教你js实现附件预览和下载得功能实现
  18. Android离线文字转语音(TTS)原生实现
  19. select标签默认选项
  20. 电源系统优化设计,低压差稳压器(LDO)如何选型?

热门文章

  1. CentOS 之 make 安装
  2. Java-getter和setter
  3. 因特网计算机地址被称为什么,因特网上每台计算机有一个规定的“地址”,这个地址被称为地址.A.TCPB.IPC.WebD.以上都不对...
  4. Idea打包:scala打成jar包
  5. C++学习课件(三)
  6. Spring学习笔记 使用annotation配置实现Bean的auto-wiring (自动绑定)
  7. 华为OSPF多区域理论,路由重分发,末梢区域和完全末梢区域的优化,NSSA区域的优化
  8. NMF学习练习:做电影推荐
  9. 关于同一ip有的电脑不能上网有的可以上网的解决方法
  10. 是谁在我的心里打了个结(二十六)乱七八糟