静态代码块、构造代码块和构造方法的执行顺序

静态代码块和构造代码块结构如下: 
static { 
静态语句代码块 


{ 构造代码块 } 

特点:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。而构造代码块随着对象的创建而执行,每创建一次对象就执行一次构造代码块。优先级:静态代码块>构造代码块(普通初始化块)>构造方法

 1 public class Test_Static_Class {  
 2     //静态代码块  
 3     static {  
 4          
 5        System.out.println("静态代码块");  
 6    }  
 7    {  
 8        System.out.println("普通代码块1");  
 9    }  
10    
11    public   Test_Static_Class() {  
12        System.out.println("执行了构造方法");  
13 }  
14    //普通的成员方法  
15    public void test() {  
16        System.out.println("在方法中的普通代码块");  
17        //普通的代码块  
18        {  
19            System.out.println("普通代码块");  
20        }  
21         
22 }  
23    public static void main(String[] args) {  
24     System.out.println("执行了主方法");  
25     System.out.println("--------------------");  
26     new Test_Static_Class();  
27     System.out.println("------第二次创建对象---------------");  
28     new Test_Static_Class();  
29     System.out.println("------第三次创建对象---------------");  
30     new Test_Static_Class().test();  
31 }  
32    
33    {  
34        System.out.println("普通代码块2");  
35    }  
36 }  
View Code

1. 多次创建对象,静态代码块只执行一次,且最先执行

2. 接下来执行的是非静态语句代码块(即:构造代码块) ,会每创建一个对象执行一次,且多个构造代码块会由上到下的执行。

3. 在接下来执行的是构造方法,构造方法也是每创建一个对象就会执行一次

4. 在接下来就是调用普通的方法中的代码块,执行的顺序,在方法中没有什么特殊的。

对于静态属性,与静态代码块一样,也是在类加载时就会被自动执行,属于整个类的属性。

  静态方法只能直接访问静态成员,不能直接访问非静态成员,如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来间接的访问非静态变量. 对于静态方法中也不能直接使用this对象。

 

若有继承的情况:

 1 public class Demo {
 2     public static class ClassA {
 3         public ClassA() {
 4             System.out.println("ClassA");
 5         }
 6         
 7         static  {
 8             System.out.println("static A class");
 9         }
10         
11         {
12             System.out.println("A class");
13         }
14     }
15     
16     public static class ClassB  extends ClassA {
17         public ClassB() {
18             super();
19             System.out.println("ClassB");
20         }
21         
22         static {
23             System.out.println("static B class");
24         }
25         
26         {
27             System.out.println("B class");
28         }
29         public void print() {
30             System.out.println("B print");
31         }
32     }
33     
34     public static void main(String []args) {
35         new ClassB();
36     }
37     
38     static  {
39         System.out.println("static Demo class");
40     }
41     
42     {
43         System.out.println("Demo class");
44     }
45 
46 }

结果:

static Demo class
static A class
static B class
A class
ClassA
B class
ClassB

原因:首先加载Demo类文件,执行Demo类中的static代码块;执行main函数中的new ClassB(),因为继承ClassA,加载ClassA,执行ClassA中的static代码块->加载ClassB,执行ClassB中的static代码块;

执行classA的构造代码块->执行classA的构造函数->执行classB的构造代码块->执行classB的构造函数

 1 public class Demo {
 2     public static class ClassA {
 3         public ClassA() {
 4             System.out.println("ClassA");
 5         }
 6     }
 7     
 8     static  {
 9         System.out.println("static A class");
10     }
11     
12     {
13         System.out.println("A class");
14     }
15     
16     public static class ClassB  {
17         public ClassB() {
18             System.out.println("ClassB");
19         }
20         
21         static {
22             System.out.println("static B class");
23         }
24         
25         {
26             System.out.println("B class");
27         }
28         public void print() {
29             System.out.println("B print");
30         }
31     }
32     
33     public static void main(String []args) {
34         new ClassB();
35     }
36 
37 }
View Code

让ClassB不在继承ClassA

结果:

 

 1 public class ExA {  
 2     static {  
 3         System.out.println("父类--静态代码块");  
 4     }  
 5    
 6     public ExA() {  
 7         System.out.println("父类--构造函数");  
 8     }  
 9    
10     {  
11         System.out.println("父类--非静态代码块");  
12     }  
13    
14     public static void main(String[] args) {  
15         new ExB();  
16     }  
17 }  
18    
19 class ExB extends ExA {  
20     static {  
21         System.out.println("子类--静态代码块");  
22     }  
23     {  
24         System.out.println("子类--非静态代码块");  
25     }  
26    
27     public ExB() {  
28         System.out.println("子类--构造函数");  
29     }  
30 } 
View Code

结果:

父类--静态代码块
子类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数

 

若一个类(用B表示)继承其他类(用A表示),则在new B()时,执行A的静态代码块(只执行一次)--->执行B的静态代码块(只执行一次)——>执行A的非静态代码块——>A的构造方法——>执行B的非静态代码块——>B的构造方法。

原文地址:https://www.cnblogs.com/lezhifang/p/6646351.html