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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© hel 中级黑马   /  2013-11-3 00:03  /  1142 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Problem {

public static void main(String[] args) {
A ab=new B();
    new B();
}       

}
public class  A{
static {
System.out.println("1");
}
public A(){
System.out.println("A");
}
}
public class B extends A{
static {
System.out.println("2");
}
public B(){
System.out.println("B");
}
}

说明一下原因?

评分

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

查看全部评分

5 个回复

倒序浏览
对象初始化过程:
1.在栈内建立变量
2.类加载进内存
3.执行静态代码块
4.在堆内存中开辟空间,分配内存地址
5.在堆内存中建立对象的特有属性,并进行默认初始化
6.对属性进行显示初始化
7.对对象进行构造代码块初始化
8.对对象进行对应的构造函数初始化
9.将内存地址赋给栈内存中的变量


你这里执行A ab=new B();这句代码时把A、B类都加载 打印里面的静态代码块  然后执行构造函数  因为子类B继承父类A  public B(){
System.out.println("B");
}
这里面有一句隐式的super(); 语句所以执行父类构造函数public A(){
System.out.println("A");
} 然后再继续执行子类B中的构造函数中的剩下代码,A ab=new B();代码执行完毕  打印出1  2   A   B(换行)

再继续执行主函数中的new B();代码, 因为之前已经加载了AB类 因此不再执行静态代码块  打印  A  B

最后结果:

1
2
A
B
A
B

评分

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

查看全部评分

回复 使用道具 举报 2 0
对象初始化过程:
1、 如果存在继承关系,就先父类后子类;
2 、如果在类内有静态变量和静态块,就先静态后非静态,最后才是构造函数;
3 、继承关系中,必须要父类初始化完成后,才初始化子类。

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
当父类与子类都有静态代码块和构造函数的时候,执行顺序如下:
父类静态代码块 > 子类静态代码块
父类构造函数 > 子类构造函数(先有父亲,后有孩子)
如果是多级继承关系的话,最高层的父类首先执行,然后依次递减

总结:静态优先执行,父类优先执行
注意:静态代码块是在JVM加载类的时候执行的,而且静态代码块执行且仅执行一次
构造方法和静态代码块的区别
静态代码块 当且仅当第一次执行的时候才执行,一般用于初始化。
而构造方法 是每次new对象的时候都执行,也是初始化
二者的区别在于 一个是仅执行一次 另一个是每次new对象的时候执行

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
如果问题已经解决,请及时修改主题为“提问结束”。
修改主题的方法链接
http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
public class Problem
{            
          public static void main(String[] args)
         {
                         A ab=new B();
                         new B();
          }        
}
public class  A
{
      static
     {
               System.out.println("1");
      }
      public A()
     {
               System.out.println("A");
     }
}
public class B extends A
{
      static
      {
               System.out.println("2");
      }
      public B()
     {
              System.out.println("B");
     }
}

该程序从开始执行,先执行A ab=new B();其中执行顺序是加载了A,B两个对象。原因是B继承A
      所以先从A类中执行,先执行static{System.out.println("1");};static{System.out.println("2");};原因是静态代码块随着类的加载而加载优先于对象存在
      然后执行public A(){System.out.println("A");}  最后执行类B中的构造函数public A(){System.out.println("B");}原因是B继承A,应先执行父类构造函数,查看父类是如何对这些数据进行初始化。所以结果是
1
2
A
B

      后执行new B();其中执行顺序为先执行public A(){System.out.println("A");}后执行public A(){System.out.println("B");}原因是静态代码块是随着类的加载而执行,只执行一次,因此这次不执行静态代码块,而执行构造函数,构造函数执行顺序和上面原因一样。结果是
A
B

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马