类加载、初始化的过程(包括static成员对象) |
您所在的位置:网站首页 › c类的静态成员是指什么 › 类加载、初始化的过程(包括static成员对象) |
类加载、初始化的过程
因为之前对类加载这块不感兴趣,感觉实际应用中又用不到……但工作后发现并非如此,因此学习总结一下——类加载和初始化的过程让人很绕,有些搞不明白。 首先要明白,类的加载和初始化是两个过程,同样也是总是在一起的两个过程。(菜鸡如我一直都很糊涂)。 1、加载、初始化的含义当我们第一次使用类时,就会触发类的加载、链接、初始化三个过程。(当然也有的说法会有其他过程,这里我们就简单一点,只说这三个过程)。 类加载,就是查找字节码,从字节码中创建一个class对象(由类加载器执行)链接,就是验证类中的字节码,为静态域分配存储空间初始化,就是为静态成员初始化及静态代码块执行(通俗来说就是赋值)的过程当这三个对象都完成后,我们才能进行创建对象的操作,也就是new的过程,因为创建对象必须用到类的 Class 对象。 2、类加载、初始化的时机时机就是第一次使用类时,一般包括三种情况: A的静态方法(如构造器)首次被访问时A的静态成员(如 i )首次被访问时通过Class类,创建A的class对象下面列出四种可能的情况: public Class A extends B{ public static Integer i = 0; public static Integer j = 0; public double k = 0; public double h = 0; static{ print("A被初始化"); } public static void main(String[] args) { //1、new一个对象,这是第一次使用,故A被加载并初始化 A a = new A(); //2、这是第一次使用A的静态成员,故A被加载并初始化 print(A.i); //3、这次有些特殊,这时候A被加载,但并未被初始化 Class aClass = A.class; //4、这时候A被加载并被初始化 Class aClass = Class.forName("A"); } } 3、类加载过程加载过程,就是创建class对象的过程。 我们都知道类都有一个class对象,假如有一个类A,通过A.class就可以获取这个对象,而实际上class对象就是用来创建对象的。 加载过程,就是创建A的Class对象,为后面创建A的对象做准备。 上面的例子我们知道获取类A的Class对象的两种方法: 一种是常用的A.class一种是Class的静态方法,Class.forName(“类名,需要包含包名”)这两种方法有一定的区别,就是A.class只会加载类,不会自动的初始化类。 //3、这次有些特殊,这时候A被加载,但并未被初始化 Class aClass = A.class; //4、这时候A被加载并被初始化 Class aClass = Class.forName("A"); 4、类初始化过程类的初始化过程大家就比较熟悉了,是在加载之后,一般都会进行(A.class这种就没有进行)。 总结一下,初始化顺序为: 先初始化父类(如果父类未被初始化)按顺序初始化静态成员静态代码块执行(与上一步优先级相同,按顺序来,但是一般书写在后面)调用new,创建对象初始化父类的非静态成员变量,调用父类的构造函数按顺序初始化非静态成员非静态代码块执行(与上一步优先级相同,按顺序来,但是一般书写在后面)执行构造器 public Class A extends B{ public double k = 0; public double h = 0; public static Integer i = 0; public static Integer j = 0; //这块代码和静态变量一样,只执行一次 static{ i = 1; } //这块代码和非静态变量初始化时一起执行 { k = 1; } A(){ print("A构造器执行"); } }如上面类A,它的初始化过程就是。 为 i 赋值0为 j 赋值0为 i 赋值1为 k 赋值0为 h 赋值0为 k 赋值1构造器执行,打印“A构造器执行” 5、特殊情况——静态常量在类的初始化过程中,有一种特殊情况,就是static final修饰的常量。它不需要初始化,就可以直接访问,因为它是在编译期就准备好了。 注意,需要满足两个条件: static final修饰常量比如: public static final Integer i = 0;此处的 i 是不需要被初始化,就可以直接访问的。 但是下面: public static final Integer j = ClassInitializarion.rand.nextInt(1000);此处的 j 并不是常量,所以需要初始化之后才能访问,也就是说,访问 j 时,会触发类的初始化。 那上面的类A,用static修饰的成员,也是需要初始化吗? public static Integer i = 0;是的,对 i 访问时,i 需要先被链接,分配存储空间后,再执行初始化 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |