Thinking:理解static执行顺序

class Bowl {
  Bowl(int marker) {      ---------------------3,5构造
    System.out.println("Bowl(" + marker + ")");
  }
  void f(int marker) {   ----------------------7,被table调用
    System.out.println("f(" + marker + ")");
  }
}

class Table {
  static Bowl b1 = new Bowl(1);     -----------------2,构造之前,也先static变量
  Table() {                         -----------------6,变量已全部构造完成,执行构造函数
    System.out.println("Table()");
    b2.f(1);                        -----------------调用bow的f()
  }
  void f2(int marker) {
    System.out.println("f2(" + marker + ")");
  }
  static Bowl b2 = new Bowl(2);    ------------------4,第二个static变量的构造
}

class Cupboard {
  Bowl b3 = new Bowl(3);             -------------------11,static构造完后,构造非static成员
  static Bowl b4 = new Bowl(4);         -----------------9,先static成员构造
  Cupboard() {                         ----------------12,成员已经构造好,执行构造函数
    System.out.println("Cupboard()");
    b4.f(2);                       --------------13,调用bow的f()
  }
  void f3(int marker) {
    System.out.println("f3(" + marker + ")");
  }
  static Bowl b5 = new Bowl(5);         ----------------10,按次序构造static成员
}

public class StaticInitialization {
  public static void main(String[] args) {
    System.out.println(
      "Creating new Cupboard() in main");           -----------14,成员已经构造好,执行main函数体,首先执行此句
    new Cupboard();                      ------------------15,构造临时Cupboard对象
    System.out.println(
      "Creating new Cupboard() in main");
    new Cupboard();
    t2.f2(1);
    t3.f3(1);
  }
  static Table t2 = new Table();    -------------------1,先static变量
  static Cupboard t3 = new Cupboard();-----------------8,继续构造static成员
}


运行结果如下
Bowl(1)
Bowl(2)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)
===========================

##static型的变量或者方法叫做类变量和类方法
类变量是在该类加载到内存的同时就进行初始化的
而非static变量是在产生实例时进行初始化

因为要执行一个static方法main(),因此要先把该类加载到内存并同时进行static变量的初始化

因此static Bowl bl = new Bowl(1);要在main函数开始执行之前就执行了

##看一下编译StaticInitialization.java的class目录,会发现虽然编译的只是一个.java文件,但由于java文件里声明了4个class,所以实际由这个java文件产生了4个class文件。
下面,你看是运行StaticInitialization.class,此时系统只载入这个类,其它三个类还没有载入,而在StaticInitialization.class有两句static语句,于是系统开始寻找这两句语句指定的类Table 和 Cupboard ,找到了开始载入,所以载入就发生了,自然也就开始初始化这两个类中的static。

##当类被装入jvm的时候,static的代码执行一次,以后就不再执行

##这个例子体现了类变量和实例变量的区别:
类变量即在变量前有"static"修饰,没有的即为实例变量;
类变量在每个类中只出现一次,不管这个类创建了多少实例,它使用的内存仅分配一次;
而实例变量是为类的每个实例分配的,在创建类的实例时,系统就为这个类中的所有实例变量分配内存。
在上面的例子中,由于b3是实例变量,所以每分配一个实例,就创建一个新的b3,所以它的输出是多次的

 

##构造类前先构造父类(如果父类还有父类,则先构造这个父类的父类,类推)
构造类的时候,先构造static变量(按代码顺序),构造完成后,构造非static变量
变量全部构造好以后,进入构造函数

##静态变量初始化是在类被初次调用的瞬间发生的,类中的非静态变量是在进入构造函数内部前初始化的,记住这两点,就可以很清楚地理解你的输出
当涉及到一个类时总会生成静态成员;然后若要生成这个类的实例,再调用initializer(默认的或人为创建的);调用构件器;完成创建。若运行一个类则会在初始化完静态成员后进入main这个入口,不会创建类的实例,除非在main的实现里有new出实例的代码。
##jvm先要构造静态对象,然后调用main(),,在对static的定义中指出,在编译时当装载一个类时会先装载其中的静态的方法。后才是构造方法。

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值