java变量的初始化顺序
2015-12-29 16:41
375 查看
假设子类B继承了父类A,当执行语句new B()或者new B(…)语句之后
1. 类的装载 (多次实例化只装载一次)
(1). 首先要进行类A和B的装载(类只有在使用New调用创建的时候才会被 java类装载器装入),先装载父类A,再装载子类B
2. 静态初始化 (多次实例化只初始化一次)
(1). 装载父类A后,完成静态动作(包括静态代码块和变量,它们的级别是相同的,按代码中出现的顺序初始化), 这里需要注意的是装载静态代码的时候,首先为静态变量分配内存空间,赋上默认值,但不把 = 后面的值赋给它(如果存在=后面的值),然后再按出现的顺序依次执行(包括static变量赋值和static代码块).
3. 实例化 (每次实例化都初始化)
(1). 在实例化子类B之前,先要实例化父类A(包括非静态代码块和变量,它们的级别是相同的,按代码中出现的顺序初始化),这里同样需要注意的是在执行代码之前,首先为成员变量分配内存空间,赋上默认值,但不把 = 后面的值赋给它(如果存在=后面的值),然后再按出现的顺序依次执行(包括实例变量赋值和实例代码块),与static初始化类似.
`
(2). 执行父类A的构造方法,这里如果子类B不指定,则执行父类A的默认构造方法,若父类没有默认的构造方法,则需要子类指定需要执行父类A的某个构造方法,否则编译不通过.
补充:
后来遇到一种情况, 存在子类方法覆盖方法的情况.
这里父类的构造方法调用了draw()方法, 但实际调用的是子类中的方法, 方法中访问了变量 i, 结果为0. 所以java在实例化的时候, 都已经将类(父类和子类)中的变量和方法都已经分配好了内存空间,并且变量赋值为默认值, 然后再按照上述的规则进行初始化.
1. 类的装载 (多次实例化只装载一次)
(1). 首先要进行类A和B的装载(类只有在使用New调用创建的时候才会被 java类装载器装入),先装载父类A,再装载子类B
2. 静态初始化 (多次实例化只初始化一次)
(1). 装载父类A后,完成静态动作(包括静态代码块和变量,它们的级别是相同的,按代码中出现的顺序初始化), 这里需要注意的是装载静态代码的时候,首先为静态变量分配内存空间,赋上默认值,但不把 = 后面的值赋给它(如果存在=后面的值),然后再按出现的顺序依次执行(包括static变量赋值和static代码块).
// 比如这种情况也是ok的 static{ i = 10; } public static int i = 20;
(2). 装载子类B后,同样完成静态动作,同父类A装载.
3. 实例化 (每次实例化都初始化)
(1). 在实例化子类B之前,先要实例化父类A(包括非静态代码块和变量,它们的级别是相同的,按代码中出现的顺序初始化),这里同样需要注意的是在执行代码之前,首先为成员变量分配内存空间,赋上默认值,但不把 = 后面的值赋给它(如果存在=后面的值),然后再按出现的顺序依次执行(包括实例变量赋值和实例代码块),与static初始化类似.
`
(2). 执行父类A的构造方法,这里如果子类B不指定,则执行父类A的默认构造方法,若父类没有默认的构造方法,则需要子类指定需要执行父类A的某个构造方法,否则编译不通过.
public B() { } /** 如果父类有默认构造super()就等同于如下代码 */ public B() { super(); /** 如果父类没有默认构造super(), 则这里需要指定, 如super(...) */ }
(3). 子类B的成员实例化,与父类A实例化类似.
(4). 最后执行子类B的构造方法.
补充:
后来遇到一种情况, 存在子类方法覆盖方法的情况.
public class B extends A { public int i = 10; public B() { System.out.println("B draw"); } public void draw() { System.out.println("B draw " + i); } public static void main(String[] args) { B b = new B(); b.draw(); } } class A { public void draw() { System.out.println("A draw"); } public A() { System.out.println("begin"); draw(); System.out.println("end"); } } /* 输出是 begin B draw 0 end B draw B draw 10 */
这里父类的构造方法调用了draw()方法, 但实际调用的是子类中的方法, 方法中访问了变量 i, 结果为0. 所以java在实例化的时候, 都已经将类(父类和子类)中的变量和方法都已经分配好了内存空间,并且变量赋值为默认值, 然后再按照上述的规则进行初始化.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树