Java 静态语句块、语句块、构造函数执行顺序

本文通过单类和多类继承的例子详细解析了Java中静态代码块与非静态代码块的执行顺序,强调了静态代码块仅在类加载时执行一次的特点。

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

静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)
一、单类例子
public class Static {
       public static int k = 0;
       public static Static s1 = new Static("t1");
       public static Static s2 = new Static("t2");
       
       public static int i = print("i");
       public static int n = 99;
       private int a = 0;
       public int j = print("j");
      
        //非静态代码块
       {
             print("构造块");
       }
       //静态代码块      
       static
       {
             print("静态块");
       }
       //构造方法
       public Static(String str){
             System.out.println((++k)+":"+str);
             ++i;++n;
       }
       
       public static int print(String str){
             System.out.println((++k)+":"+str);
             ++n;
             return ++i;
       }
       
       public static void main(String[] args) {
       }

输出结果:
1:j
2:构造块
3:t1
4:j
5:构造块
6:t2
7:i
8:静态块

注解:
首先执行 public static Static s1 = new Static("t1");因为他是出现最早的静态语句,new Static("t1")之后,执行Static类中的public int j = print("j")这一句,可是为什么不执行静态代码块呢?
静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次 ,而且给变量或者代码块添加static关键字后,Static对象就不再拥有该属性了,被添加static关键字的属性会统一交给Static类去管理,即多个Static对象只会对应一个被static修饰的属性


二、多类继承例子
class Parent{
    static String name = "hello";
    {
        System.out.println("3 parent block");
    }
    static {
        System.out.println("1 parent static block");
    }
    public Parent(){
        System.out.println("4 parent constructor");
    }
}

class Child extends Parent{
    static String childName = "hello";
    {
        System.out.println("5 child block");
    }
    static {
        System.out.println("2 child static block");
    }
    public Child(){
        System.out.println("6 child constructor");
    }
}

public class StaticIniBlockOrderTest {
    public static void main(String[] args) {
        new Child();
    }
}

结果:
1 parent static block
2 child static block
3 parent block
4 parent constructor
5 child block
6 child constructor

2. 顺序:
   1)执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容;
   2)当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构   造方法;
   3)父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。
总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
而且子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值