这种东西在平时开发中基本用不到,也很少遇到,如果没遇到过的话恐怕有些人还不知道代码块的概念,但是在笔试面试中出现的概率却很大,所以这里记录一下。
class A{
A(){
System.out.println("A的构造函数");
}
{
System.out.println("A的普通代码块");
}
static {
System.out.println("A的静态代码块");
}
}
class B extends A{
B(){
System.out.println("B的构造函数");
}
{
System.out.println("B的普通代码块");
}
static {
System.out.println("B的静态代码块");
}
}
public class Test {
public static void main(String[] args) {
A a = new B(); //输出顺序:A的静态代码块->B的静态代码块->A的普通代码块->A的构造函数->B的普通代码块->B的构造函数
System.out.println();
a = new B(); //输出顺序:A的普通代码块->A的构造函数->B的普通代码块->B的构造函数
}
}
可以看出执行的优先级:
父类静态代码块 > 子类静态代码块 > 父类普通代码块 > 父类构造方法 > 子类普通代码块 > 子类构造方法
再次对a赋值新对象时没有了静态代码块的输出,这是因为静态的代码块或是方法都是只加载一次
=========================================================================
下面添加静态变量的情况
class A{
A(){
//这里可以使用a1,因为先执行静态代码再执行非静态代码,所以这里a1已经定义好了
System.out.println("A的构造函数");
System.out.println("a1 = "+a1+" a2 = "+a2);
}
{
//这里可以使用a1,因为先执行静态代码再执行非静态代码,所以这里a1已经定义好了
a1 = a1+1;
System.out.println("A的普通代码块"+a1);
}
static int a1 = 1;
static {
a2 = 3; //这里可以对a2赋值,但是对后面定义a2变量没有影响
//a2 = a2+2; //不可以这么写,因为a2在后面才定义
//System.out.println("A的静态代码块"+a2); //同理,这里不可以调用a2
}
static int a2 = 2;
static {
//可以使用a2,因为上面定义了a2;静态代码块或是静态变量执行顺序就是它们的先后定义顺序
System.out.println("A的静态代码块"+a2);
}
}
public class Test {
public static void main(String[] args) {
new A();
}
}
静态变量和静态代码块一样的优先级别,所以在普通代码块和构造方法里面可以直接使用,但是在静态代码块里面使用静态变量,那就决定于他们被定义的先后顺序。