JAVA类加载与初始化顺序

刺骨的言语ヽ痛彻心扉 2022-05-16 11:21 397阅读 0赞

类的生命周期

7个阶段依次为:Loading Verification Preparation Resolution Initialization Using Unloading

144324_BSaw_26712.jpg

类加载的双亲委派模型

各个加载器都是先委托自己的父加载器加载类,若确实没加载到再自己来加载

于是java默认的类查找加载顺序是自顶向下的,树状结构

双亲委托的意图是保证java类型体系中最基础的行为一致,优先加载JDK中的类

175233_jJRs_26712.jpg

加载器主要有四种:

  • jvm启动类加载器bootstrap loader,用c++实现为jvm的一部分(仅指sun的hotspot),负责 JAVA_HOME/lib下面的类库中的类的加载,这个加载器,java程序无法引用到。
  • 扩展类加载器Extension Loader,由sun.misc.Launcher$ExtClassLoader类实现,可在java中使用,负责JAVA_HOME/lib/ext 目录和java.ext.dir目录中类库的类的加载。
  • 应用系统类加载器Application System Loader,由sun.misc.Louncher$AppClassLoader实现,负责加载用户类路径中类库中的类,如果没有使用自定义的加载器,这个就是默认的 加载器!
  • 用户自定义加载器 自己定义从哪里加载类的二进制流

加载 验证 准备 初始化和卸载 的顺序是确定的,而“解析”不一定在初始化之前,很有可能在初始化之后,实现java的伟大特性。

  1. package com.cyb.diffcult.类加载;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. /**
  5. * 作者 : iechenyb<br>
  6. * 类描述: final 修饰的为常量 子类继承父类时的初始化顺序
  7. * 1.首先初始化父类的static变量和块,按出现顺序
  8. * 2.初始化子类的static变量和块,按出现顺序
  9. * 3.初始化父类的普通变量,调用父类的构造函数
  10. * 4.初始化子类的普通变量,调用子类的构造函数<br>
  11. * 创建时间: 2018年1月18日
  12. */
  13. public class Singleton2 {
  14. Log log = LogFactory.getLog(getClass());
  15. public static final int a = init(5, "static final int a");
  16. public static int counter1;// 在构造方法*
  17. public static int counter2 = init2("static int c2", 120);// 在构造方法执行之后执行
  18. public final int c = init(6, "final int c");
  19. public int counter3 = init3("int c3", 110);// 初始化-最后
  20. public static final int b = init(4, "static final int b");
  21. public final int d = init(7, " final int d");
  22. public static int counter4 = init2("static int c4", 0);// 在构造方法执行之后执行
  23. static {
  24. System.out.println("静态语句块1");
  25. }
  26. private Singleton2(String msg) {
  27. System.out.println(msg);
  28. }
  29. private static int init(int num, String bs) {
  30. System.out.println("初始化常量" + bs);
  31. return num;
  32. }
  33. private Singleton2() {
  34. System.out.println("构造方法执行!");
  35. ++counter1;
  36. ++counter2;
  37. ++counter3;
  38. }
  39. static {
  40. System.out.println("静态语句块2");
  41. }
  42. private static Singleton2 sin = new Singleton2();// 与静态语句块按照顺序执行
  43. public static int init2(String msg, int val) {
  44. System.out.println(msg);
  45. return val;
  46. }
  47. public int init3(String msg, int val) {
  48. System.out.println(msg);
  49. return val;
  50. }
  51. public static Singleton2 getInstance() {
  52. return sin;
  53. }
  54. public static void main(String[] args) {
  55. Singleton2 sin = Singleton2.getInstance();
  56. System.out.println(sin.counter1);// 1
  57. System.out.println(sin.counter2);// 1
  58. System.out.println(sin.counter3);// 110->666
  59. }
  60. /**
  61. * 初始化常量static final int a
  62. static int c2
  63. 初始化常量static final int b
  64. static int c4
  65. 静态语句块1
  66. 静态语句块2
  67. 初始化常量final int c
  68. int c3
  69. 初始化常量 final int d
  70. 构造方法执行!
  71. 1
  72. 121
  73. 111
  74. */
  75. }

执行顺序:

/**
* 常量分 普通常量 和静态常量
* 作者 : iechenyb

* 类描述: final 修饰的为常量 子类继承父类时的初始化顺序
* 1.首先初始化父类的static变量和块,按出现顺序
* 2.初始化子类的static变量和块,按出现顺序
* 3.初始化父类的普通变量,调用父类的构造函数
* 4.初始化子类的普通变量,调用子类的构造函数

* 创建时间: 2018年1月18日
*/

发表评论

表情:
评论列表 (有 0 条评论,397人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java初始化

    一、类的加载与ClassLoader的理解 1、加载 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的ja

    相关 java顺序

    在java中类的加载、初始化都是在程序运行期完成的,虽然会稍微增加开销,但是却很大的增加了灵活性,我们可用在运行期间动态的去网络或其他地方加载一个二进制流来作为程序代码的一部分

    相关 Java顺序

    Java初始化顺序 1在new B一个实例时首先要进行类的装载。(类只有在使用New调用创建的时候才会被java类装载器装入) 2,在装载类时,先装载父类A,再装载子类