上篇文章讲解了static关键字的相关用法,接下来我们学习如何初始化一个static 变量,这就涉及到代码块的相关知识
1. 普通代码块(Local Code Block)
普通代码块是在方法内使用的大括号 {}
包围的代码段,它可以用来限制变量的作用范围,提高代码的可读性。普通代码块的作用域在大括号内。
示例:
public class Main {
public static void main(String[] args) {
int x = 10;
// 普通代码块
{
int y = 20;
System.out.println("x: " + x); // 可以访问外部变量 x
System.out.println("y: " + y); // 只能在此代码块中访问 y
}
// System.out.println("y: " + y); // 错误,y 已经超出了代码块的作用范围
}
}
解释:
y
是在代码块内部声明的变量,只能在代码块内访问,出了这个块,y
就无法使用了。普通代码块通常用于限制变量的作用范围,避免变量在方法的其他部分被误用。
2. 静态代码块(Static Block)
静态代码块是使用 static
关键字定义的代码块,它会在类加载时执行,且只执行一次。静态代码块通常用于初始化静态变量或执行一次性的设置。
特性:
- 静态代码块在类加载时执行一次,早于类的任何对象创建。
- 适合初始化类级别的资源或配置。
示例:
public class Example {
static int a;
// 静态代码块
static {
a = 10; // 初始化静态变量
System.out.println("静态代码块执行");
}
public static void main(String[] args) {
System.out.println("静态变量 a: " + a); // 输出静态变量 a 的值
}
}
运行结果:
静态代码块执行
静态变量 a: 10
解释:
- 静态代码块在类加载时执行,因此 "静态代码块执行" 会在
main
方法之前输出。静态代码块通常用于初始化静态变量或者执行一些类加载时需要的操作。
3. 实例代码块(Instance Initialization Block)
实例初始化代码块是没有 static
修饰符的代码块,它在每次创建对象时都会执行。它的执行优先级高于构造函数,即实例初始化代码块会在构造函数之前执行。
特性:
- 实例初始化代码块在每次创建对象时执行,用于对象的初始化。
- 适合在构造函数之前执行一些共享的初始化逻辑。
示例:
public class Example {
int a;
// 实例初始化代码块
{
a = 20; // 初始化实例变量
System.out.println("实例初始化代码块执行");
}
public Example() {
System.out.println("构造函数执行");
}
public static void main(String[] args) {
Example obj1 = new Example(); // 创建第一个对象
Example obj2 = new Example(); // 创建第二个对象
}
}
运行结果:
实例初始化代码块执行
构造函数执行
实例初始化代码块执行
构造函数执行
解释:
- 实例初始化代码块在每次对象创建时都会执行,并且早于构造函数。即每次创建对象时,都会先执行实例初始化代码块,然后再执行构造函数。因此无论创建多少个对象,实例初始化代码块都会被执行多次。
4. 构造代码块执行顺序
在一个类中,如果包含了静态代码块、实例初始化代码块以及构造函数,它们的执行顺序是固定的。
执行顺序:
- 静态代码块(只执行一次,类加载时执行)
- 实例初始化代码块(每次创建对象时执行)
- 构造函数(在实例初始化代码块之后执行)
示例:
public class Example {
static {
System.out.println("静态代码块执行");
}
{
System.out.println("实例初始化代码块执行");
}
public Example() {
System.out.println("构造函数执行");
}
public static void main(String[] args) {
Example obj1 = new Example(); // 创建第一个对象
Example obj2 = new Example(); // 创建第二个对象
}
}
运行结果:
静态代码块执行
实例初始化代码块执行
构造函数执行
实例初始化代码块执行
构造函数执行
解释:
- 静态代码块在类加载时首先执行,而且只执行一次。
- 每次创建对象时,都会依次执行实例初始化代码块和构造函数,实例初始化代码块的执行早于构造函数。