问题引入
今天在做笔试题时遇到这样一个问题:1
2
3
4
5
6
7
8
9
10
11
12
13
14public class Test {
static Test t1 = new Test();
{
System.out.println("blockA");
}
static
{
System.out.println("blockB");
}
public static void main(String[] args)
{
Test t2 = new Test();
}
}
在以上代码中涉及到了静态代码块、构造代码块,之前没接触过这个概念,所以查资料记录学习了一下。
静态代码块
什么是静态代码块?
写法:1
2
3
4static
{
}
它有什么特点?
- 用static申明,JVM加载类时执行,仅执行一次,执行完成便销毁。
- 静态代码块的执行优先级高于非静态的初始化块。
构造代码块
什么是构造代码块?
写法:1
2
3{
}
它有什么特点?
构造代码块的作用是给对象进行初始化,只有当对象创建才会执行,且执行顺序优于构造函数。并且不同于构造函数,构造代码块针对所有的对象,而构造函数针对对应的对象。
构造函数
构造函数只有在建立对象的时候在会调用与之相应的构造函数,不建立对象是不会运行构造函数的。一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次。
总结
- 静态块其实就是给类初始化的,而构造代码块是给对象初始化的。
- 静态代码块只会运行一次
- 静态块中的变量是局部变量,与普通函数中的局部变量性质没有区别。
- 一个类中可以有多个静态代码块,执行顺序按照位置决定。
- 执行顺序优先级:静态块>main()>构造块>构造方法
回到上面的问题:1
2
3
4
5
6
7
8
9
10
11
12
13
14public class Test {
static Test t1 = new Test();
{
System.out.println("blockA");
}
static
{
System.out.println("blockB");
}
public static void main(String[] args)
{
Test t2 = new Test();
}
}
输出:1
2
3blockA
blockB
blockA
分析:
t1也是静态变量,所以按照声明顺序执行,先创建对象t1,运行其构造代码块,输出blockA,之后运行静态代码块,输出blockB,最后运行main函数。
创建对象时得调用顺序:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器