最近在参加一些面试,偶尔会看到一些面试题,涉及到Java代码的执行顺序问题。作为一个菜鸟级的代码搬运工,平时还真没留心过这个问题,下面就遇到的一个面试题给出自己的验证结果,供一些和我一样对这些技术没那么多热情但又不得不了解的小伙伴参考。
题目:请写出下面代码的输出结果
class HelloA {
HelloA() {
System.out.println("HelloA");
}
{
System.out.println("I'm A Class");
}
static {
System.out.println("static A");
}
}
public class HelloB extends HelloA {
HelloB() {
System.out.println("HelloB");
}
{
System.out.println("I'm B Class");
}
static {
System.out.println("static B");
}
public static void main(String[] args) {
new HelloB();
}
}
答案:
static A
static B
I'm A Class
HelloA
I'm B Class
HelloB
总结:
1、 当JVM加载一个类时,JVM会根据属性的数据类型先赋默认值。然后再进行静态属性初始化,并为静态属性分配内存空间,静态方法的声明,静态块的加载,没有优先级之分,按出现顺序执行,静态部分仅仅加载一次。至此为止,必要的类都已经加载完毕,对象就可以被创建了。
2、当我们需要new一个对象时,此时会调用构造方法,但是在调用构造方法之前,(此刻1已经执行结束,除非被打断而暂停)执行动态属性定义并设置默认值。然后动态属性初始化,分配内存,构造块,普通方法声明(只是加载,它不需要初始化,只有调用它时才分配内存,当方法执行完毕后内存立即释放),没有优先级之分,按出现顺序执行。最后进行构造方法中赋值。当再次创建一个对象,不再执行静态部分,仅仅重复执行普通部分。
注意:如果存在继承关系,创建对象时,依然会首先进行动态属性进行定义并设默认值,然后父类的构造器才会被调用,其他一切都是先父类再子类(因为子类的static初始化可能会依赖于父类成员能否被正确初始化),如果父类还有父类,依次类推。
想要了解更多,可以学习http://www.cnblogs.com/greatfish/p/5771548.html#3967173