【Java】 静态初始化 + 实例初始化

本文详细探讨了Java中的静态初始化和实例初始化过程。静态初始化在类加载时进行,仅执行一次,而实例初始化在每次创建对象时执行。初始化顺序为:静态对象 -> 非静态对象 -> 构造器。对于类Panda,类加载、静态初始化、对象分配、字段初始化和构造器依次执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、静态初始化

//: initialization/StaticInitilization.java
// Specifying initial values in a class definition

class Bowl{
    Bowl(int marker){
        System.out.println("Bowl (" + marker + ")");
    }
    void f1(int marker){
        System.out.println("f1(" + marker + ")");
    }
}
class Table{
    static Bowl bowl1 = new Bowl(1);
    Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker) {
        System.out.println("f2(" + marker + ")");
    }
    static Bowl bowl2 = new Bowl(2);
}
class Cupboard{   
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard(){
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker) {
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
    public static void main(String[] args){
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

上述代码输出结果如下

Bowl (1)
Bowl (2)
Table()
f1(1)
Bowl (4)
Bowl (5)
Bowl (3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl (3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl (3)
Cupboard()
f1(2)
f2(1)
f3(1)

程序执行main()静态方法,必须先加载类 StaticInitialization,然后静态域 table 和 cupboard 被初始化,这导致它们对应的类也被加载,并且它们都包含静态域 Bowl 对象,因此 Bowl 对象也被加载。

静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用对象的静态成员,那么静态成员永远都不会创建。只有在第一个对象被创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后静态对象不会再次被初始化。

初始化的顺序先是静态对象,如果他们尚未因为前面的对象创建过程而被初始化,然后是非静态对象。

对象创建过程总结,假设有个Panda的类:

1:即使没有显示的使用 static 关键字,构造器实际上也是静态方法。因此,当首次创建类型为Panda的对象时,或者Panda类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Panda.class文件。

2:然后载入Panda.class,有关静态初始化的所有动作都会被执行,因此,静态初始化只在Class对象首次加载的时候进行一次。

3:当用 new Panda() 创建对象的时候,首先将在堆上为Panda对象分配足够的存储空间。

4:这块存储空间会被清零,这就自动地将Panda对象中的所有基本数据类型都设置成了默认值。

5:执行所有出现于字段定义处的初始化动作。

6:执行构造器

二、实例初始化

//: initialization/Mugs.java
// Java "Instance Initialization."

class Mug{
    Mug(int marker){
        System.out.println("Mug(" + marker + ")");
    }
    void f(int marker){
        System.out.println("f(" + marker + ")");
    }
}
public class Mugs {
    Mug mug1;
    Mug mug2;     // 实例初始化子句 在构造器之前执行
    {           // 非静态实例初始化 每次 new 一个对象 都会执行一次
        mug1 = new Mug(1);
        mug2 = new Mug(2);
        System.out.println("mug1 & mug2 initialization");
    }
    Mugs(){    // 每次 new 一个对象 执行对应的构造器
        System.out.println("Mugs()");
    }
    Mugs(int i){
        System.out.println("Mugs(int)");
    }
    public static void main(String[] args){
        System.out.println("Inside main()");
        new Mugs();
        System.out.println("new Mugs completed");
        new Mugs(1);
        System.out.println("new Mugs(1) completed");
    }
}

运行结果如下

Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialization
Mugs()
new Mugs completed
Mug(1)
Mug(2)
mug1 & mug2 initialization
Mugs(int)
new Mugs(1) completed

实例初始化和静态初始化代码看起来一样,实例初始化没有static 关键字。

总结一下:

1:静态初始化,静态初始化会在创建对象是最先执行,而后是非静态对象,最后是构造器。当第一次创建对象是已经执行了静态初始化,下次再创建该对象时,不再执行静态初始化操作。

2:实例初始化:先执行实例初始化,再执行构造器初始化。每次当你创建一个对象时,实例初始化都会被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值