日期:2014-05-20  浏览次数:20628 次

一道Java笔试题,能详细说明下结果吗
请写出下面这段代码的输出结果?
class Shape{
  Shape(int i){
  System.out.println("This is Shape" + i);
  }
}
public class Circle extends Shape{
  static Shape s1 = new Shape(1);
  Shape s2 = new Shape(3);
  Circle(int i){
  super(i);
  System.out.println("This is Circle" + i);
  }

  public static void main(String args[]){
  Circle c1 = new Circle(2);
  }
}

------解决方案--------------------
This is Shape1
This is Shape2
This is Shape3
This is Circle2

分析过程:
1、JVM在运行class时,首先会扫描一次全部的程序,静态块优先级最高,因为它们会存储在JVM的公共内存区域。
2、接着会调用构造方法,构造方法调用的顺序是,JVM会先扫描类的继承关系,然后从最顶层的构造方法向下执行。
3、执行到指定类内部时,会先处理类中定义的实例变量,然后再执行构造方法内部的代码。
所以得到上面的结果。
------解决方案--------------------
你只需要记住:
1、静态先于非静态,静态包括静态实例变量,静态代码块;
2、父类先于子类;
3、同级的以代码书写顺序执行;
4、同类中实例变量先与构造方法;

所以最后顺序就是:
先父类的静态-子类的静态-父类实例变量-父类构造方法-子类实例变量-子类构造方法
为什么JVM会用这个顺序来初始化对象,其实想都想得明白:如果静态的东西不先初始化,我们的静态方法就没法调用了;如果实例变量不先初始化,我们的构造方法里如果用到了那个变量就会出错;如果父类的不先初始化,我们子类的构造方法用到了父类的东西也会出错。
所以结果就是
shape 1(子类静态)
shape 2(父类构造方法)
shape 3(子类实例变量)
circle 2(子类构造方法)

------解决方案--------------------
是先调用Circle的构造函数,然后执行到super(i)在调用基类的
你可以理解为super是执行基类的同名方法
你也可以重写自己的方法不调用基类的,把super去掉就好