Java中代码块的执行

Java中代码块的执行

代码块的格式

{执行的语句}

代码块的主要用途

当我们定义了代码块之后,我们每一次调用构造器,代码块的语句都会被执行一次。我们可以看出代码块在构造器的第一列就被调用执行了。如果有多个代码块则会按照顺序进行调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Test {
public static void main(String[] args) {
aa b= new aa("小明");
aa c= new aa("小明",99);
}
}
class aa{
public String name;
public int age;
{

System.out.println("我是代码块");
}
public aa(String name){
this.name=name;
System.out.println(name+age);
}
public aa(String name,int age){
this.name=name;
this.age=age;
System.out.println(name+age);
}
}

image-20220705113224248

注意事项

  • static代码块叫做静态代码块,作用时对类进行初始化,而且他随着类的加载而执行,并且只会执行一次。如果时普通代码块,每创建一个对象,就会执行。那么类什么时候会被加载那???①创建对象实例时(new)②创建子类对象实例,父类也会被加载③使用类的静态成员(静态方法,静态变量)

对于第一种情况我们已经演示过,我们来看第二种情况,当我们创建aa的子类bb,并且实例化bb,会调用父类的代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {
public static void main(String[] args) {
bb b=new bb();
}
}
class aa{
public static String name;
public int age;
static {

System.out.println("我是代码块");
}
{

System.out.println("我是代码块2");
}
}
class bb extends aa{

}

image-20220705113622578

对于第三种情况,我们调用aa的静态方法,发现代码块也被调用了,至于为什么第二个非静态代码块没有执行,是因为这只是加载了类,却并没有创建类实例对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test {
public static void main(String[] args) {
System.out.println(aa.name);
}
}
class aa{
public static String name="张三丰";
public int age;
static {

System.out.println("我是代码块");
}
{

System.out.println("我是代码块2");
}
}

image-20220705113717597

  • 对于在调用过程中同时出现静态初始化变量与静态代码块,其中顺序按照代码中的顺序进行执行。比如:在下面这个代码中静态初始化变量在前,静态代码块在后,优先执行静态初始化变量,而普通代码块最后执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Test {
public static void main(String[] args) {
aa A=new aa();
}
}
class aa{
public static int n1=get1();
{
System.out.println("我是一个普通代码块");
}
static {

System.out.println("我是第一个静态代码块");
}
public static int get1(){
System.out.println("我是getn1函数");
return 100;
}
}

image-20220705113851394

所以说,我们代码块在执行过程中会优先完成静态代码块,静态初始化等,然后在去完成普通的变量初始化与普通代码块。

  • 我们经常会遇到类的继承关系,那么在继承关系中我们代码块的执行会怎么执行。

执行如下代码,正如我们前面提到的,static在加载类时就被调用了,后面创建类时,会优先执行父类的构造器,然后执行子类的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Test {
public static void main(String[] args) {
aa A=new aa();
}
public Test(){
System.out.println("我是父类的无参构造器");
}
{
System.out.println("我是父类的代码块");
}
}
class aa extends Test{
public int n1=get1();
{
System.out.println("我是一个普通代码块");
}
static {

System.out.println("我是一个静态代码块");
}
public static int get1(){
System.out.println("我是getn1函数");
return 100;
}
}

image-20220705114106955

总结

代码块是继承执行顺序为

  1. 父类静态代码块与静态属性(子类加载中必须进行父类加载)
  2. 子类的静态代码块与静态属性(子类加载的执行)
  3. 父类的普通代码块与普通属性初始化(子类创建对象调用父类)
  4. 父类构造方法
  5. 子类的普通代码块与普通属性初始化
  6. 子类的构造方法
  7. 静态代码块只能调用静态的成员与方法,而普通代码块则可以调用任意成员与方法。因为在普通代码块执行时,静态代码块已经全部执行完毕。