java中 static 的执行顺序问题

本文通过示例代码详细解析了Java中父类与子类的静态及非静态代码块的执行顺序,揭示了静态代码块先于非静态代码块执行,且遵循从父类到子类的执行原则。

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

关于static的 父类和子类的执行顺序问题:

首先用代码来证明:


父类如下:
public class staticDemo {
static {
int x=5;
System.out.println("父亲的静态代码块执行了");
}
static {
int x=5;
System.out.println("父亲的静态代码块2执行了");
}
static void print(){

System.out.println("父亲的静态方法代码块执行了");
}
public staticDemo(){
System.out.println("父亲的构造方法代码块执行了");
}
public static void main(String[] args) {
staticDemo.print();
//staticDemo sd=new staticDemo();
//sd.print();
// TODO Auto-generated method stub
System.out.println("父亲的主方法代码块执行了");
}
{
System.out.println("父亲的非静态代码块执行了");
}
}

子类:



public class sonStatic extends staticDemo{
static {
System.out.println("儿子的静态代码块执行");
}
public sonStatic(){
System.out.println("儿子的构造函数块执行");
}
{
System.out.println("儿子的非静态代码块执行");
}
static void printf(){
System.out.println("儿子的静态方法执行");
}
public static void main(String args[]){
sonStatic.printf();
sonStatic s=new sonStatic();
}
}

输出:

父亲的静态代码块执行了
父亲的静态代码块2执行了
儿子的静态代码块执行
儿子的静态方法执行
父亲的非静态代码块执行了
父亲的构造方法代码块执行了
儿子的非静态代码块执行
儿子的构造函数块执行


总结如下:

首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法

<think>首先,用户的问题是:“我想理解Java类中static代码块、静态变量和静态方法的执行顺序请问javastatic代码块静态变量静态方法执行顺序”。这是一个关于Java中静态元素执行顺序的查询。根据系统级指令:-所有行内数学表达式必须使用$...$格式,但这个问题是关于Java的,没有数学表达式,所以可能不需要。-独立公式必须使用$$...$$格式,但同样,这里没有公式。- LaTeX语法正确,但Java代码不需要LaTeX。 -使用中文回答。 -生成相关问题。-回答中引用的段落末尾自然地添加引用标识,例如[^1]。用户可见层指令: -回答结构清晰,帮助用户逐步解决问题。-尽量保证回答真实可靠。-参考站内引用:提供了三个引用,但用户说“上述引用仅供参考,并不是用户真正的需求”,所以我需要基于Java知识回答,而不是直接引用这些内容。参考引用内容: -[^1]讨论了static执行顺序,包括静态变量和静态代码块。- [^2]详细解释了static静态变量、方法、代码块的作用和初始化顺序。 -[^3]给出了一个例子,说明静态代码块、静态变量、成员变量等的执行顺序。 关键点从引用中提取: -static修饰的元素在类加载时初始化。-静态变量和静态代码块的初始化顺序按照它们在代码中的顺序。 -静态内容优先于非静态内容。-在类加载时,静态代码块和静态变量初始化,然后才是对象创建时的成员变量和构造方法。用户的问题聚焦在:static代码块、静态变量和静态方法的执行顺序。注意,静态方法本身不是初始化的一部分;静态方法在调用时执行,但初始化是关于静态变量和代码块的。执行顺序:1.当类首次被加载时(例如,第一次访问类时),所有static元素初始化。 2.初始化顺序:静态变量和静态代码块按照它们在代码中出现的顺序执行。3.静态方法在调用时执行,不涉及初始化顺序;它们只是方法。所以,顺序是:-静态变量初始化(赋值)。-静态代码块执行。 它们按声明顺序执行。 例如,在代码中: ```javapublic classExample{static inta =10; //静态变量初始化static {System.out.println("Staticblock1");//静态代码块}staticint b=20;static{System.out.println("Static block2");} }``` 加载类时,顺序是:- a初始化(10)-第一个静态代码块执行- b初始化(20) -第二个静态代码块执行静态方法,如publicstatic voidmyMethod(),在调用时执行,比如Example.myMethod(),不参与初始化顺序。 回答结构:1.解释static元素的初始化时机:类加载时。2.描述执行顺序:静态变量和静态代码块按代码顺序执行。 3.强调静态方法在调用时执行。4.提供简单代码示例。5.生成相关问题。使用中文。生成相关问题: 基于主题,可以问:1.静态元素和非静态元素的执行顺序差异? 2.如何优化静态初始化? 3.静态代码块的使用场景?4.在继承中的执行顺序?引用标识:如果引用参考内容,但用户说“请尽可能多的参考用户上一次的问题和你的回答”,但这是第一次交互,所以基于知识回答。如果需要,可以自然添加引用,但引用是站内的,可能不直接相关。 最终回答大纲: -介绍:静态元素在类加载时初始化。 -详细顺序:静态变量和静态代码块按声明顺序执行。-示例代码。 -静态方法说明。 -相关问题。</think>### Javastatic代码块、静态变量和静态方法的执行顺序Java中,`static`修饰的元素(包括静态代码块、静态变量和静态方法)在类加载阶段初始化,而非对象创建阶段。执行顺序遵循严格的规则,确保静态内容优先初始化。以下是详细解释: #### 1. **初始化时机** - 当类首次被加载时(例如,首次访问类的静态成员或创建对象),JVM会初始化所有`static`元素。 - 静态内容仅初始化一次,且优先于非静态内容(如成员变量或构造方法)[^2][^3]。 #### 2. **执行顺序规则** - **静态变量和静态代码块按声明顺序执行**:在类加载时,静态变量赋值和静态代码块按照它们在代码中出现的顺序依次执行。 - 例如: ```java public class Example { static int a = initA(); // 静态变量1 static { System.out.println("静态代码块1"); // 静态代码块1 } static int b = 20; // 静态变量2 static { System.out.println("静态代码块2"); // 静态代码块2 } private static int initA() { System.out.println("初始化a"); return 10; } } ``` 加载类时,顺序为: 1. `a`初始化(调用`initA()`)。 2. 执行第一个静态代码块。 3. `b`初始化。 4. 执行第二个静态代码块。 - **静态方法不参与初始化顺序**:静态方法(如`public static void myMethod()`)仅在调用时执行,与类加载无关。例如,`Example.myMethod()`会在需要时运行,不影响静态变量或代码块的初始化[^2]。 #### 3. **关键原则** - **静态优先于非静态**:所有静态元素初始化完成后,才会处理成员变量、构造代码块或构造方法。 - **顺序依赖代码位置**:如果静态变量和静态代码块交错声明,JVM严格按代码顺序执行。 - **继承中的顺序**:在子类加载时,先初始化父类的静态内容,再初始化子类的静态内容[^3]。 #### 4. **示例验证** 运行以下代码: ```java public class Test { static { System.out.println("静态代码块执行"); } static int var = initVar(); private static int initVar() { System.out.println("静态变量初始化"); return 5; } public static void main(String[] args) { System.out.println("main方法执行"); } } ``` 输出: ``` 静态代码块执行 静态变量初始化 main方法执行 ``` 说明:静态代码块和静态变量按顺序执行,`main`方法(静态方法)在类加载后调用。 #### 5. **注意事项** - 静态代码块常用于一次性初始化静态变量或资源(如数据库连接)[^2]。 - 静态方法不能直接访问非静态成员,因为非静态内容尚未初始化[^2]。 - 如果多个类依赖,加载顺序遵循类引用关系,但每个类内部的静态顺序不变[^3]。 通过理解这些规则,您可以避免初始化顺序导致的错误,如空指针异常[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值