Java对象创建过程:静态代码块,构造代码块,构造函数执行顺序

一、普通代码块

void a() {
}

普通代码块(局部代码快)是在方法名后面用 {} 括起来的代码段,不能够单独存在,必须要紧跟在方法名后面且必须使用方法名调用它,作用是限定变量的生命周期和提高效率

二、构造代码块

{ 
 int a = 1;
}

构造代码块是在类中方法外用 {} 括起来的代码,作用是把所有构造方法中相同的内容抽取出来,将来在调用构造方法的时候会去自动调用构造代码块,构造代码快优先于构造方法

构造代码块的作用是给对象进行初始化

构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容

三、静态代码块

static {
	int i = 1}
  • 它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
  • 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
  • 静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别。
  • 一个类中可以有多个静态代码块

四、Java类初始化顺序

单个类的执行顺序:
public class Animal {
    private static String a = "静态成员变量";
    private String b = "普通成员变量";
    public Animal() {
        System.out.println("构造函数执行!!!");
    }

    {
        System.out.println(b);
        System.out.println("构造代码块执行!!!");
    }


    static {
        System.out.println(a);
        System.out.println("静态代码块执行!!!");
    }

    public static void main(String[] args) {
        Animal animal = new Animal();

    }
}

执行结果:

静态成员变量
静态代码块执行!!!
普通成员变量
构造代码块执行!!!
构造函数执行!!!

注意,静态成员变量和静态代码块之间执行顺序不固定,它们是遵从代码的顺序,在静态代码块中使用的变量,不可以定义在代码块之后,普通成员变量和构造代码块之间也是如此

继承类情况:
public class Dog extends Animal {
    private String a = "子类普通成员变量";
    private static String b = "子类静态变量";
    public Dog() {
        System.out.println("子类构造方法执行");
    }

    {
        System.out.println(a);
        System.out.println("子类构造代码块");
    }

    static {
        System.out.println(b);
        System.out.println("子类静态代码块执行");
    }

    public static void main(String[] args) {
        new Dog();
    }
}

创建Animal子类Dog,查看执行顺序
运行结果:

父类静态成员变量
父类静态代码块执行!!!
子类静态变量
子类静态代码块执行
父类普通成员变量
父类构造代码块执行!!!
父类构造方法执行!!!
子类普通成员变量
子类构造代码块
子类构造方法执行

对象创建过程:

  • 在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完成类的初始化
  • 类初始化过程中或初始化完毕后,根据具体情况才会去对类进行实例化
  • 虚拟机分配内存来存放对象自己的实例变量及其从父类继承过来的实例变量(即使这些从超类继承过来的实例变量有可能被隐藏也会被分配空间)
  • 分配内存的时候会对类的普通成员变量赋予默认值(零值)
  • 内存分配完成之后,Java虚拟机就会开始对新创建的对象代码进行初始化
  • 主要初始化普通成员变量,构造代码块,构造函数

这里大家会疑惑,静态代码块和静态变量是什么时候初始化的呢?

前面中JVM系列博客已经说明,类加载的过程中会进行上述操作,这里简单描述一下:

  • 类加载的准备阶段为类中的所有静态变量分配内存空间,并为其设置一个初始值
  • 类初始化过程中Java编译器将所有的类变量初始化语句和静态初始化语句收集在一起,放在一个特殊方法(clinit方法)中,然后被虚拟机执行,这个过程只会发送一次,后面new对象不会再次发生
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值