学过Java的朋友,应该会有人没听说话“静态代码块”和“构造代码块”的吧?笔者在第一次学习Java的时候也没听说过这一部分的内容。当然如果有知道的大神,就可以略过了。不管你对Java了解多少,我还是从头开始讲起吧。
还记得笔者的一篇讲解构造器的文章么?如果不知道,请找到这篇文章把他看完。其实在实例化对象的时候,构造器并不是首先被执行的。那在执行构造器之间究竟还有什么被执行了?那就是我要介绍的静态代码块和构造代码块。
“块”这个概念大家都很清楚吧?不管在C/C++或者Java都有这个概念。用大括号将一系列代码阔起来,就成了一个块。
//这就是一个块,str具有块作用域,也是一个局部变量
{
String str = new String("Hello, world!");
System.out.println(str);
}
上面的代码就是一个块。大家都知道在C中代码是基于函数的,即一切的代码都应该在函数中,具体执行的是函数,而不是某个单独的代码。即,你不能独立于函数之外去执行代码。下面的代码在编译的时候就会报错。int main(int argc, char* argv[])
{
return 0;
}
int a = 0;
a = 10 + 5; //这样的做法是不对的
只有这样编写,才合乎语法的要求:
int main(int argc, char* argv[])
{
function();
return 0;
}
int a = 0;
void function()
{
a = 10 + 5;
}
而在Java中,类才是代码的一个单元。即,代码都是由一个一个类组成的。在类中再遵循C/C++中的规则(代码放在函数中)。但不是所有的代码都遵循这一规则。那就是代码块。它可以独立于方法的。下面给一个例子来说明:
public class Lin {
{ //这是构造代码块
System.out.println("This is normal block");
t1 = new Test(1);
t2 = new Test(2);
t3 = new Test(3);
}
static //这是静态代码块
{
System.out.println("This is static");
t = new Test(0);
}
public static void main(String args[]) {
System.out.println("main()");
new Lin();
new Lin();
}
public Lin() {
System.out.println("Lin()");
}
public Test t1;
public Test t2;
public Test t3;
public static Test t;
}
class Test {
public int a = 0;
Test() {
<pre name="code" class="java"> System.out.println("Test");}
Test(int a) {
this.a = a;
System.out.println("Test(" + a + ")");
}
}
正如上面的代码所示,构造代码块就是一个普通的块。静态代码块是一个普通的块并且面前加了一个关键字“static”。先看一下程序的运行结果:
This is static
Test(0)
main()
This is normal block
Test(1)
Test(2)
Test(3)
Lin()
This is normal block
Test(1)
Test(2)
Test(3)
Lin()
很明显,最先运行的是静态代码块和构造代码块,最后运行的才是构造器。所以它俩就是在构造器运行之前所运行的代码。那他们到底是有什么作用呢?
静态代码块是用来初始化静态域的,他只能初始化静态域! 而构造代码块是用来初始化对象的域。因为静态域是属于类的,因此实例化多少个对象,静态代码块只能运行一次。初始化完这一系列工作之后,才调用类的构造器,来执行客户端程序员所要初始化的域。这两种块是类的设计人员所做的工作。为了给客户端开发人员提供一个接口,让他们也能初始化域,构造器就是一个不二的选择。
还有一个比较经典的细节就是,类的初始化顺序。读者应该看到这面代码的执行结果了吧?它的输出结果为什么是这个顺序的呢?这就涉及到类的初始化顺序,请看笔者相关的文章。
本文详细介绍了Java中的静态代码块和构造代码块的概念及其使用场景。通过实例演示了它们在类初始化过程中的执行顺序及如何用于初始化静态域和对象域。
1816

被折叠的 条评论
为什么被折叠?



