一、普通代码块
在Java中,普通代码块(也称为实例初始化块或非静态初始化块)是用于在创建对象时执行代码的特殊代码块。它用于初始化实例变量或执行一些每次创建对象时都需要执行的代码。普通代码块在每次创建对象时执行,并且每次执行都会重新执行其中的代码。
普通代码块通常用于以下场景:
- 初始化实例变量:当实例变量需要复杂的初始化逻辑时,可以使用普通代码块。
- 执行每次创建对象时都需要执行的代码。
下面是一个简单的例子,演示了普通代码块的使用:
public class A {
public int num;
{
num=10;
System.out.println("A类的代码块...");
}
public A(){
System.out.println("A类的无参构造。。。");
}
}
class Test{
public static void main(String[] args) {
A a = new A();
System.out.println(a.num);
A a2 = new A();
}
}
结果如下:
A类的代码块...
A类的无参构造。。。
10
A类的代码块...
A类的无参构造。。。
在这个例子中,A
类有一个实例变量num
和一个普通代码块。当创建A
的实例时,普通代码块会被执行,初始化num
变量,并打印一条消息。每次创建A
的实例时,普通代码块都会执行。可以看到,构造方法A()
被调用了两次,因为创建了两个实例,普通代码块也被执行了两次,因为每次创建对象时都需要执行。
二、static代码块
在Java中,static
代码块(也称为静态初始化块)是用于在类加载时执行代码的特殊代码块。它用于初始化类的静态变量或执行一些只需要执行一次的代码。static
代码块在类加载时执行,并且只执行一次,无论创建了多少个该类的实例。
static
代码块通常用于以下场景:
- 初始化静态变量:当类的静态变量需要复杂的初始化逻辑时,可以使用
static
代码块。 - 执行一次性操作:如果有一些代码只需要在类加载时执行一次,可以使用
static
代码块。
下面是一个简单的例子,演示了static
代码块的使用:
public class A {
public static int num;
static{
num=10;
System.out.println("A类的代码块...");
}
public A(){
System.out.println("A类的无参构造。。。");
}
}
class Test{
public static void main(String[] args) {
A a = new A();
System.out.println(a.num);
A a2 = new A();
}
}
结果如下:
A类的代码块...
A类的无参构造。。。
10
A类的无参构造。。。
在这个例子中,A
类有一个静态变量num
和一个static代码块。当创建A
的实例时,静态代码块会被执行,初始化num
变量,并打印一条消息。无论创建了多少个A
的实例,static
代码块只会执行一次。
在main
方法中,我们创建了两个A
的实例,可以看到,构造方法A()
被调用了两次,因为创建了两个实例,但static
代码块只执行了一次,因为它是在类加载时执行的。
区别:
一、定义与位置
-
普通代码块
- 定义:在方法、循环、判断等语句中出现的代码块,通常用花括号
{}
包围。 - 位置:可以出现在方法体内除
()
外的任何地方,包括方法体内部、循环体内部、判断语句内部等。
- 定义:在方法、循环、判断等语句中出现的代码块,通常用花括号
-
static代码块
- 定义:在类中定义并使用
static
关键字修饰的代码块。 - 位置:它不能出现在方法体或者其他代码块内,只能位于类体中。
- 定义:在类中定义并使用
二、执行时机与生命周期
-
普通代码块
- 执行时机:随着对象的创建而执行,每次创建对象时都会执行一次。也可以看作随着构造器的调用而执行,因为编译器在编译时会把普通代码块插入到每个构造函数的最前面(如果某个构造函数调用了其他的构造函数,则不会重复插入以避免执行多次)。
- 生命周期:与对象的生命周期一致,对象存在时普通代码块中的变量也有效,对象销毁时这些变量也随之失效。
-
static代码块
- 执行时机:在类加载时执行,且只执行一次。无论创建多少个对象,静态代码块都只会执行一次。类加载通常发生在创建对象实例、创建子类对象(导致父类也被加载)、或使用静态成员变量时。
- 生命周期:与类的生命周期一致,类加载时静态代码块中的变量就有效,直到类被卸载时这些变量才失效。
三、访问权限与作用域
-
普通代码块
- 访问权限:可以访问类的实例变量和实例方法,以及局部变量(如果位于方法体内)。
- 作用域:通常受限于其所在的方法、循环或判断语句的作用域。
-
static代码块
- 访问权限:只能直接访问类的静态变量和静态方法,不能直接访问实例变量和实例方法(需要通过类的实例对象来访问)。
- 作用域:在整个类中都有效,因为静态代码块在类加载时就已经执行了。
总结
- 普通代码块:随着对象的创建而执行,用于初始化实例变量或执行一些需要在对象创建时进行的操作。每次创建对象都会执行一次。
- static代码块:在类加载时执行一次,用于初始化静态变量或执行一些需要在类加载时进行的操作。无论创建多少个对象,静态代码块都只执行一次。