- 说明:
- 父类为Fa,子类为Child
- 成员变量=全局变量 在类内部在方法外部定义的变量
- 静态成员=static 修饰的全局变量
- 成员变量=在方法内部定义的
- 将加载、连接、初始化过程 统称为 :全加载 为何里面单独的加载进行区分
- 疑问:静态代码块的执行和静态变量的赋值哪个先?
- 涉及的知识点:
- 什么情况下才加载类,已知的几种情况
- 当一个类为启动类时候,先加载其父类
- 当new 一个子类的时候,先加载其父类
- 子类对象和父类的加载先后顺序
- 加载的时候可以做什么
- 类的加载机制-加载、连接、初始化
- 各阶段各做了什么
- 加载的时候可以做什么
- 父类和子类的成员变量-通过不同的引用型变量访问的输出不同
- 父类和子类的方法-通过不同的引用型变量调用输出不同
- 成员变量的存放位置
- 局部变量的存放位置
- static成员的存放位置
- 常量池中存放的数据
- 什么情况下才加载类,已知的几种情况
- 具体讲解
- 什么情况下才加载类,已知的几种情况
- 当一个类为启动类时候,先加载其父类:验证实验如下
-
/** * * 实验一 当子类为启动类时候,先全加载父类,再全加载子类 * * 验证过程: * 验证1-在子类父类中都写 静态代码块 * 验证2-比较静态代码块的执行顺序 * * 结论:哪个静态代码块先执行 说明哪个类先被加载(不一定全家在,验证在实验三) * PS:静态代码块的执行发生在全加载过程的 准备阶段或者是初始化阶段,看静态代码块的顺序(验证在实验二) * */
/** * 实验一 * @author liuyan * 时间 2015年5月2日20:38:25 * 地点 宿舍 */ public class Child extends Fa { static { // 静态代码块-在一个类的加载阶段执行 System.out.println("子类 静态代码块"); } public static void main(String[] args) { } } class Fa { static { System.out.println("父类 静态代码块"); } }
结果: 父类 静态代码块 子类 静态代码块
- 实验二:静态代码块执行发生在 全加载的初始化阶段
-
/* * 实验二 静态代码块的执行发生在全加载过程的 连接-准备阶段或者初始化阶段 * 验证1.静态变量写在 静态变量定义语句之前 * *说明: *-先执行的是 准备过程中的 给静态变量分配内存并初始化为其默认值 *-再执行初始化阶段 将程序员想赋予静态变量的值赋值给静态变量 *-再执行的是 静态代码块 *解释: *-要是先执行静态代码块的内容的话,首先编译语句会报错:找不到变量 shuju * * */
/* * 实验二 静态代码块的执行发生在全加载过程的 连接-准备或者 初始化阶段 * */ public class Child extends Fa { static { // 静态代码块-在一个类的加载阶段执行 System.out.println("子类 静态代码块"); } public static void main(String[] args) { } } class Fa { static{ System.out.println("Fa static Area"); } static int shuju = 2; /* * 在Fa.class一旦从硬盘被加载, * 则在加载其二进制代码, * 在连接-验证阶段验证代码完整性和规范性, * 在连接-准备阶段给静态变量分配内存并赋予默认值, * 在连接-解析阶段将 符号引用转换为直接引用先不说 * 在初始化阶段 为类的静态变量(也 称类变量)赋予正确的初始值,也就是程序员想赋予的值,在这里是2 * * * 接着执行静态代码块内的代码 */ static { System.out.println("子类的静态变量shuju的值"+shuju); } }
执行结果: Fa static Area 子类的静态变量shuju的值2 子类 静态代码块
PS:父类的静态变量初始化完成,并执行完静态代码块中的值之后才加载子类,此外静态代码块按顺序执行
- 实验三
-
/* * 实验二 静态代码块的执行发生在全加载过程的 连接-准备或者 初始化阶段 * */ public class Test extends Fa { /* * 实验三:哪个静态代码块先执行 说明哪个类先被加载(不一定全加载 */ public static void main(String[] args) { // Child child;-结果 Fa static Area说明 只有父类加载类,子类没有加载 // Fa fa=new Fa();//结果同上 Child child = new Child();// 结果Fa static Area 子类 静态代码块 // Fa fa =new Child();//结果同上 } } class Child extends Fa { static { // 静态代码块-在一个类的加载阶段执行 System.out.println("子类 静态代码块"); } } class Fa { static { System.out.println("Fa static Area"); } }
-
-
- 什么情况下才加载类,已知的几种情况
时间: 2024-10-05 05:31:31