Java类中的静态属性、静态代码块块、非静态属性、非静态代码块块、构造函数在初始化时的执行顺序

序言

   前几天在复习J2SE的时候,看到了这个Java类在new的过程中,静态域、静态块、非静态域、非静态块、构造函数的执行顺序问题。就想着自己总结写一下,便于以后查阅

总结:

    以下是我整理好的结果;在java类new一个对象的过程中,它们的执行顺序如下:

     (当java类没有被继承时)

1.    实现自身的静态属性和静态代码块。

    注意:它们两个的执行顺序根据自身出现的顺序决定

2.    实现自身的非静态属性和非静态代码块。

3.    执行自身的构造函数。

(当java类被继承时,其子类被new对象的执行过程,初始化顺序如下:)

   

 1、初始化父类静态属性

 2、执行父类静态代码块

 3、初始化子类静态属性

 4、执行子类静态代码块

 5、初始化父类实例变量

 6、执行父类动态代码块

 7、执行父类构造方法

 8、初始化子类实例变量

 9、执行子类动态代码块

10、执行子类构造方法

静态代码块和动态代码块

静态代码块:

static{

}

动态代码块:

{

}

静态代码块和非静态代码块的异同点如下:

相同点:都是JVM加载类时且在构造函数执行之前执行,在类中都可以定义多个,为静态属性赋值、执行一些必要的初始化操作

不同点:静态代码块在非静态代码块之前执行(静态代码块执行顺序 > 非静态代码块执行顺序)。但是静态代码块只在第一次new对象时执行一次,之后不再执行。而动态代码块每new一次就执行一次。


例子:

public class Test{
public static void main(String[] args){
MyClass mc = new MyClass();
}
}
class MyClass{
static String str1 = "MyClass 静态属性";
static{
//静态代码块 类级别
System.out.println(str1);
System.out.println("MyClass  静态代码块");
}
String str2 = "MyClass 非静态属性";
{
//动态代码块   对象级别
System.out.println(str2);
System.out.println("MyClass  动态代码块");


}
public MyClass(){
System.out.println("MyClass  构造方法执行");
}
}

结果:

MyClass 静态属性
MyClass  静态代码块
MyClass 非静态属性
MyClass  动态代码块

MyClass  构造方法执行

当java类被继承时,其子类被new对象时,它们的执行顺序,如下:

(Sub类为MyClass类的子类)

public class Test{
public static void main(String[] args){
Sub s = new Sub();
}
}
class MyClass{
static String str1 = "MyClass 静态属性";
static{
//静态代码块 类级别
System.out.println(str1);
System.out.println("MyClass  静态代码块");
}
String str2 = "MyClass 非静态属性";
{
//动态代码块   对象级别
System.out.println(str2);
System.out.println("MyClass  动态代码块");


}
public MyClass(){
System.out.println("MyClass  构造方法执行");
}
}
class Sub extends MyClass{
static String str3 = "sub 静态属性";
static{
//静态代码块 类级别
System.out.println(str3);
System.out.println("sub  静态代码块");
}

String str4 = "sub 非静态属性";
{
//动态代码块   对象级别
System.out.println(str4);
System.out.println("sub  动态代码块");

}


public Sub(){
System.out.println("sub  构造方法执行");
}
}

结果:

MyClass 静态属性
MyClass  静态代码块
sub 静态属性
sub  静态代码块
MyClass 非静态属性
MyClass  动态代码块
MyClass  构造方法执行
sub 非静态属性
sub  动态代码块
sub  构造方法执行

<think>好的,我现在需要回答用户关于Java静态初始化和动态初始化特点的问题。首先,我得回忆一下这两种初始化的基本概念,确保自己理解正确。静态初始化通常和相关,而动态初始化可能和对象实例相关?或者是和代码块有关? 接下来,我应该明确两者的定义。静态初始化应该是在加载的候进行的初始化,可能包括静态变量的赋值和静态代码块。而动态初始化可能是在对象创建进行的,比如构造方法、实例变量赋值或实例代码块。不过,用户提到的“动态初始化”在Java中是否有官方术语?或者这是对比静态初始化的一种说法? 我需要验证这些概念是否正确。比如,静态初始化块使用static关键字,而实例初始化块则没有。静态初始化第一次被加载执行,且只执行一次;而实例初始化则在每次创建新对象执行。这可能就是用户所说的动态初始化? 然后,考虑用户的问题,他们可能想了解两者的区别、使用场景以及语法上的不同。需要分点说明特点,可能包括执行机、语法结构、应用场景、初始化次数等。 另外,要注意举例说明,这样更清晰。比如静态初始化块的例子,动态初始化(实例初始化块或构造函数)的例子。同,要强调静态初始化只能处理静态成员,而动态初始化处理实例成员。 还需要检查是否有其他相关的点,比如静态初始化不能访问静态成员,而动态初始化可以访问静态静态成员。异常处理方面,静态初始化块不能抛出已检查异常,而动态初始化可以? 另外,可能存在的误区需要指出,比如动态初始化是否包括实例初始化块和构造方法,或者用户可能混淆了数组的静态和动态初始化(虽然这里的问题应该是指初始化)。 总结结构:先分别介绍静态和动态初始化的定义,然后分点列出各自的特点,再比较它们的区别,最后给出使用场景的例子。确保语言简洁,用中文,符合用户要求的结构清晰,逐步解答。</think>在Java中,静态初始化和动态初始化是两种不同的成员初始化方式,其核心区别在于**执行机**和**作用对象**。以下是详细对比和分析: --- ### 一、静态初始化级别) **定义**:在加载阶段对**静态成员(static变量、静态代码块)**进行初始化。 **特点**: 1. **执行机**:首次被加载到内存执行(如首次访问、创建实例或调用静态方法)。 2. **执行次数**:仅执行一次。 3. **语法结构**: ```java static { // 静态代码块(可包含复杂逻辑) staticVar = 100; } ``` 4. **作用范围**:只能操作静态成员,无法访问实例变量或方法。 5. **异常处理**:不能抛出已检查异常(Checked Exceptions),必须内部处理。 **示例**: ```java public class MyClass { static int staticVar; static { staticVar = computeInitialValue(); // 静态方法初始化 } } ``` --- ### 二、动态初始化(实例级别) **定义**:在对象实例化对**实例成员(static变量、实例代码块、构造方法)**进行初始化。 **特点**: 1. **执行机**:每次通过`new`创建对象执行。 2. **执行次数**:每创建一个对象执行一次。 3. **语法结构**: ```java { // 实例代码块(每次构造对象前执行) instanceVar = 10; } public MyClass() { // 构造方法中的初始化逻辑 } ``` 4. **作用范围**:可访问静态成员和实例成员。 5. **异常处理**:允许抛出已检查异常(需在构造方法声明中抛出)。 **示例**: ```java public class MyClass { int instanceVar; { instanceVar = 20; // 实例代码块初始化 } public MyClass(int value) { instanceVar = value; // 构造方法初始化 } } ``` --- ### 三、关键区别对比 | **特性** | 静态初始化 | 动态初始化 | |------------------|--------------------------|--------------------------| | 作用对象 | 静态成员(级别) | 实例成员(对象级别) | | 执行机 | 加载(一次) | 对象实例化(多次) | | 访问权限 | 仅静态成员 | 静态+实例成员 | | 异常处理 | 不可抛出已检查异常 | 可抛出已检查异常 | --- ### 四、使用场景建议 1. **静态初始化**: - 初始化静态资源(如数据库连接池)。 - 加载配置文件或静态常量。 2. **动态初始化**: - 根据参数动态设置对象属性。 - 执行对象创建的依赖检查或资源分配。 --- ### 五、常见误区 - **数组初始化的干扰**:Java中数组的“静态初始化”(如 `int[] arr = {1,2,3};`)和“动态初始化”(如 `int[] arr = new int[3];`)是另一组概念,静态/动态初始化无关。 - **代码块顺序**:实例代码块会在构造方法前执行,多个代码块代码顺序执行。 通过理解两者的特点,可以更合理地设计初始化逻辑,避免资源浪费或逻辑错误。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值