静态代码块、静态方法、构造方法的执行顺序

本文详细介绍了Java中类的构造过程及初始化顺序,包括静态与非静态代码块、构造函数的执行顺序,以及super关键字的使用。

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

java中首先是静态块先执行,静态方法,最后是构造函数。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public  class  ExA {  
     static  {  
         System.out.println( "父类--静态代码块" );  
     }  
   
     public  ExA() {  
         System.out.println( "父类--构造函数" );  
     }  
   
     {  
         System.out.println( "父类--非静态代码块" );  
     }  
   
     public  static  void  main(String[] args) {  
         new  ExB();  
     }  
}  
   
class  ExB  extends  ExA {  
     static  {  
         System.out.println( "子类--静态代码块" );  
     }  
     {  
         System.out.println( "子类--非静态代码块" );  
     }  
   
     public  ExB() {  
         System.out.println( "子类--构造函数" );  
     }  
}  
 
执行结果 
===== 
父类--静态代码块 
子类--静态代码块 
父类--非静态代码块 
父类--构造函数 
子类--非静态代码块 
子类--构造函数    

这里写图片描述


1.父类、子类之间代码块与构造方法

package com.web.test2;

public class HelloA {
    static{
        System.out.println("static A");
    }

    {System.out.println("I'm A class");}

    public HelloA(){

        System.out.println("HelloA");
    }
    public HelloA(String s){

        System.out.println(s+"HelloA");
    }

    public static void main(String[] args) {
        new HelloB();
    }
}
 class HelloB extends HelloA{
    public HelloB () {
        //只能调用一个父类的构造方法
//      super();
        super("parent");
        System.out.println("HelloB");
    }
    {System.out.println("I'm B class");}
    static{
        System.out.println("static B");
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

执行结果: 
static A 
static B 
I’m A class 
parentHelloA 
I’m B class 
HelloB


总结如下:

① 代码块于构造方法之前执行,静态于非静态之前;

② 在类第一次被调用时,加载该类,静态代码块只执行一次;

③ 项目启动时,只加载需要加载的类(比如xml中显示配置的bean,或者web.xml中的listener等),并不会将所有的类都加载(这是很可怕的事情);

④ 静态代码块只能调用静态变量;静态方法只能调用静态变量;

⑤ 非静态代码块或非静态方法可以调用任何(静态+非静态)变量。

⑥ 非静态代码块在实例化对象时,于构造方法之前执行。


2.父类、子类与super()


public class People {
    String name;
    public People() {
        System.out.println(1);
    }
    public People(String name) {
        System.out.println(2);
        this.name = name;
    }
}
 class Child extends People{
     People father;
    public Child () {
        //super()系统会默认添加的
        System.out.println(4);
    }
    public Child (String name) {
        //super()系统会默认添加的
        System.out.println(3);
        this.name = name;
        father = new People(name+":F");
    }
    public static void main(String[] args) {
        new Child("mike");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

故执行结果:132


另外一个难缠的实例:

public class ExA {  
    private static ExA a = new ExA();  
    static {  
        System.out.println("父类--静态代码块");  
    }  

    public ExA() {  
        System.out.println("父类--构造函数");  
    }  

    {  
        System.out.println("父类--非静态代码块");  
    }  

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

class ExB extends ExA {  

    private static ExB b = new ExB();

    static {  
        System.out.println("子类--静态代码块");  
    }  
    {  
        System.out.println("子类--非静态代码块");  
    }  

    public ExB() {  
        System.out.println("子类--构造函数");  
    }  
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • result as follows :
父类--非静态代码块
父类--构造函数
父类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数
子类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数


### Java 中静态方法静态代码块构造方法执行顺序 在 Java 中,程序运行时类加载的过程决定了静态方法静态代码块以及构造方法执行顺序。以下是详细的分析: #### 类加载过程中的执行顺序 当一个类被加载到 JVM 中时,其初始化阶段会按以下顺序执行: 1. **静态代码块**:静态代码块会在类加载时被执行一次,并且按照它们在源码中定义的顺序依次执行[^2]。 2. **静态变量赋值**:如果存在静态成员变量(如 `static` 字段),这些字段会被初始化并分配默认值或显式指定的初始值[^3]。 3. **静态方法调用**:静态方法可以在类加载完成后通过类名直接调用,或者由其他地方触发调用。 只有当创建对象实例时才会涉及构造方法及其相关部分: 4. **构造代码块**:每次创建新对象时都会执行构造代码块,它位于构造方法之前[^1]。 5. **构造方法**:最后执行的是与当前对象关联的具体构造方法[^1]。 因此,在整个生命周期来看,完整的执行流程可以总结如下: - 静态代码块 → (可能存在的) 静态方法调用 → 构造代码块构造方法。 需要注意的一点是,尽管静态方法可以通过对象来访问,但实际上它是属于类级别的操作;也就是说即使没有实际的对象存在也能正常工作[^2]。 下面给出一段示例代码展示这种行为模式: ```java public class ExecutionOrderExample { static { System.out.println("Static block executed"); } { System.out.println("Instance initialization block executed"); } public ExecutionOrderExample(){ System.out.println("Constructor called"); } public static void main(String[] args){ System.out.println("Before object creation"); // 创建第一个对象前后的打印语句用于区分不同时间点的行为 new ExecutionOrderExample(); System.out.println("\nCalling a static method now:"); callStaticMethod(); // 再次创建另一个对象观察重复情况下的表现差异 new ExecutionOrderExample(); } public static void callStaticMethod(){ System.out.println("Inside the static method."); } } ``` 此代码片段展示了从启动应用程序直到完成两个独立对象构建期间各个组件是如何交互工作的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值