A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孟伟娟 中级黑马   /  2012-11-21 11:01  /  1822 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孟伟娟 于 2012-11-24 21:35 编辑

分析一下代码初始化过程,为什么会出现以下打印结果?
class Bowl{
Bowl(int marker){
  System.out.println("Bowl(" + marker + ")");
}

void f1(int marker){
  System.out.println("f1(" + marker + ")");
}
}
class Table{
static Bowl bowl1 = new Bowl(1);
Table(){
  System.out.println("Table()");
  bowl2.f1(1);
}

void f2(int marker){
  System.out.println("f2(" + marker + ")");
}

static Bowl bowl2 = new Bowl(2);//(2)
}
class Cupboard{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);

Cupboard(){
  System.out.println("Cupboard()");
  bowl4.f1(2);
}

void f3(int marker){
  System.out.println("f3(" + marker + ")");
}

static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
  System.out.println("Creating new Cupboard() in main");
  
  new Cupboard();
  
  System.out.println("Creating new Cupboard() in main");
  new Cupboard();
  
  table.f2(1);
  cupboard.f3(1);
  
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}

结果为:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
通过这个程序,可以深入了解static和非static的初始化过程。
我的分析是:首先加载StaticInitialization类,执行main()方法。main方法中有static成员,先初始化static的table和cupboard,这将导致它们对应的类也被加载,先加载Table类,类中静态成员先初始化,然后构造函数初始化。结果为Bowl(1)、Bowl(2)、Table()、f1(1)。然后加载Cupboard类,同样先静态对象初始化,然后非静态对象初始化,最后构造函数初始化,结果为Bowl(4)、Bowl(5)、Bowl(3)、Cupboard()、f1(2)。main()函数中静态成员初始化完成后,其他部分按顺序执行,出现相应结果(如上)。
值得注意的是:static成员只初始化一次,之后不会再被初始化。而非静态成员会被重复初始化。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
初始化一个对象时是按这样的顺序进行的:
1、所有数据域被初始化为默认值(0, false, null)
2、按照在类声明中出现的顺序依次执行所有的域初始语句或初始化块,静态域的初始化要早于实例域的初始化
3、如果构造器第一行调用了第二个构造器,则执行第二个构造器,以此类推
4、执行这个构造器的主体

具体看下面的注释:
  1. class Bowl{
  2.         Bowl(int marker){
  3.                 System.out.println("Bowl(" + marker + ")");
  4.         }

  5.         void f1(int marker){
  6.                 System.out.println("f1(" + marker + ")");
  7.         }
  8. }



  9. class Table{
  10.         static Bowl bowl1 = new Bowl(1); //按照声明顺序 bowl1的初始化早于bowl2的初始化,然后才是Table()构造函数
  11.         Table(){
  12.                 System.out.println("Table()");
  13.                 bowl2.f1(1);
  14.         }

  15.         void f2(int marker){
  16.                 System.out.println("f2(" + marker + ")");
  17.         }

  18.         static Bowl bowl2 = new Bowl(2);//(2)
  19. }


  20. class Cupboard{
  21.         Bowl bowl3 = new Bowl(3);//静态域的初始化要早于实例域并且按照声明顺序,
  22.                                  //那么先初始化bowl4再初始化bowl5,再初始化bowl3,接着才是构造方法
  23.         static Bowl bowl4 = new Bowl(4);

  24.         Cupboard(){
  25.                 System.out.println("Cupboard()");
  26.                 bowl4.f1(2);
  27.         }

  28.         void f3(int marker){
  29.                 System.out.println("f3(" + marker + ")");
  30.         }

  31.         static Bowl bowl5 = new Bowl(5);
  32. }


  33. public class StaticInitialization {

  34.         public static void main(String[] args) {
  35.                 System.out.println("Creating new Cupboard() in main");
  36.   
  37.                 new Cupboard();
  38.   
  39.                 System.out.println("Creating new Cupboard() in main");
  40.                 new Cupboard();
  41.   
  42.                 table.f2(1);
  43.                 cupboard.f3(1);
  44.   
  45.         }
  46.         static Table table = new Table();
  47.         static Cupboard cupboard = new Cupboard();
  48. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
其实你只要掌握了一条主线一切都是浮云。
for instance:
A a = new A();
假如a是一个自定义类,这句话后台要做很多事情的。首先会检查该类有没有初始化代码块,有的话先执行。然后去执行构造函数,若是该类继承了其他类,首先会去执行父类的构造函数,执行完毕后才执行自己的构造函数,以此类推,若父类还有父类。。。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
先初始化父类的静态代码--->初始化子类的静态代码--> (创建实例时,如果不创建实例,则后面的不执行)初始化父类的非静态代码--->初始化父类构造函数--->初始化子类非静态代码--->初始化子类构造函数
http://bbs.itheima.com/forum.php ... %3D78%26typeid%3D78
回复 使用道具 举报
static      非static   

静态变量是在创建类的时候就在内存中被创建了,static也叫类变量,非static 成员变量,初始化后才会开辟内存空间
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马