您的位置:首页 > 编程语言 > Java开发

Think in Java 实例变量的初始化

2015-09-17 23:21 369 查看
说明:
  父类为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");
    }

}




      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: