一、static静态代码块、普通匿名代码块、构造方法的执行时间
static静态代码块:随着类的加载而执行,只执行一次
普通匿名代码块:随着对象的创建而执行,每new一次对象执行一次。
构造方法:在创建对象的时候,new对象的时候执行。
二、一个对象创建的过程(简单描述,默认对象的类以及被加载到内存中)
Student stu = new Student();
这一句的执行过程:
1、在栈区开辟空间保存引用 stu
2、在堆区开辟空间保存实际数据 (给对象在堆中分配空间)
3、把堆区的地址赋值给栈区的引用(将对象在堆区中的地址赋值给stu)
4、给成员变量赋默认值
5、为对象的属性进行显示的初始化
6、调用普通代码块{}
7、根据构造器完成对象创建
三、代码演示
public class StaticTest extends Base{
static{
System.out.println("StaticTest static");
}
{
System.out.println("StaticTest 匿名代码块");
}
public StaticTest(){
//这里有隐式的super() 调用父类的无参构造器
System.out.println("StaticTest constructor");
}
public static void main(String[] args) {
new StaticTest();
}
}
class Base{
static{
System.out.println("base static");
}
{
System.out.println("Base 匿名代码块");
}
public Base(){
System.out.println("base constructor");
}
}
执行结果:
base static
StaticTest static
Base 匿名代码块
base constructor
StaticTest 匿名代码块
StaticTest constructor
解释:main方法是程序的入口,执行new StaticTest();
1、那么就要加载staticTest类,但是发现它继承了Base类,那么首先需要加载Base类,在加载Base类的过程中,执行Base类中的静态代码块 打印出 base static
2、接下来加载StaticTest类,执行StaticTest类的静态代码块,打印出StaticTest static
3、类加载完成,就可以创建对象了, new StaticTest(); 此时会调用StaticTest的无参构造方法,
但是StaticTest的无参构造器中的第一行有隐式的super(), 调用super()的时候实际上是执行的new Base(),(上创建对象的过程中看到,匿名代码块的执行在构造器执行之前执行)所以打印出Base 匿名代码块
4、接下来就调用Base()构造器,打印出base constructor
5、然后就接下来执行StaticTest()构造器,同样也会先执行匿名代码块, 在执行构造器StaticTest()构造器 所以先打印出来StaticTest 匿名代码块 最后打印 StaticTest constructor