java 中的静态代码块、构造代码块、构造函数以及Java类初始化顺序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wanghang88/article/details/80119342

静态代码块:用staitc声明,jvm加载类时执行,仅执行一次;

构造代码块:类中直接用{}定义,每一次创建对象时执行;

执行顺序优先级:静态块,main(),构造块,构造方法。

a)构造函数:

1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象,构造函数时不会运行的;

2.构造函数的作用是用于给对象进行初始化;

3.一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次;

b)构造代码块:

1:构造代码块的作用是给对象进行初始化,对象一建立就运行构造代码块了,而且优先于构造函数执行,必须有对象建立,才会运行构造代码块,类不能调用构造代码块的, 而且构造代码块与构造函数的执行顺序是前者先于后者执行

2:构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

c)静态代码块:

1:它是随着类的加载而执行,只执行一次,并优先于主函数,具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的;

2:静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的;

3:静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别;

4:一个类中可以有多个静态代码块。


java中类的执行顺序:可以通过如下的测试类来说明

构造函数,构造代码块,静态代码块,不创建对象时:

public class HelloA {
    public HelloA(){//构造函数
        System.out.println("A的构造函数");    
    }
    {//构造代码块
        System.out.println("A的构造代码块");    
    }
    static {//静态代码块
        System.out.println("A的静态代码块");        
    }
    public static void main(String[] args) {
    }
}
运行结果:
A的静态代码块

构造函数,构造代码块,静态代码块,创一次建对象时:

public class HelloA {
    public HelloA(){//构造函数
        System.out.println("A的构造函数");    
    }
    {//构造代码块
        System.out.println("A的构造代码块");    
    }
    static {//静态代码块
        System.out.println("A的静态代码块");        
    }
    public static void main(String[] args) {
        HelloA a=new HelloA();    
    }
}

运行结果:
A的静态代码块
A的构造代码块
A的构造函数

构造函数,构造代码块,静态代码块,创两次建对象时:

public class HelloA {
    public HelloA(){//构造函数
        System.out.println("A的构造函数");    
    }
    {//构造代码块
        System.out.println("A的构造代码块");    
    }
    static {//静态代码块
        System.out.println("A的静态代码块");        
    }
    public static void main(String[] args) {
        HelloA a=new HelloA();
        HelloA b=new HelloA();
    }

}

运行结果:
A的静态代码块
A的构造代码块
A的构造函数
A的构造代码块
A的构造函数

对于静态变量、静态初始化块、变量、初始化块、构造器的执行顺序:

public class InitialOrderTest {
 2         /* 静态变量 */
 3     public static String staticField = "静态变量";
 4         /* 变量 */
 5     public String field = "变量";
 6         /* 静态初始化块 */
 7     static {
 8         System.out.println( staticField );
 9         System.out.println( "静态初始化块" );
10     }
11         /* 初始化块 */
12     {
13         System.out.println( field );
14         System.out.println( "初始化块" );
15     }
16         /* 构造器 */
17     public InitialOrderTest()
18     {
19         System.out.println( "构造器" );
20     }
21 
22 
23     public static void main( String[] args )
24     {
25         new InitialOrderTest();
26     }
27 }

运行结果:
      静态变量
      静态初始化块
      变量
      初始化块
      构造器

对于继承的情况:A类中有构造函数,构造代码块,静态代码块;B类中也有构造函数,构造代码块,静态代码块,B类继承A类时的执行顺序:

public class HelloA {
    public HelloA(){//构造函数
        System.out.println("A的构造函数");    
    }
    {//构造代码块
        System.out.println("A的构造代码块");    
    }
    static {//静态代码块
        System.out.println("A的静态代码块");        
    }
}
public class HelloB extends HelloA{
    public HelloB(){//构造函数
        System.out.println("B的构造函数");    
    }
    {//构造代码块
        System.out.println("B的构造代码块");    
    }
    static {//静态代码块
        System.out.println("B的静态代码块");        
    }
    public static void main(String[] args) {
        HelloB b=new HelloB();        
    }
}
运行结果:
A的静态代码块
B的静态代码块
A的构造代码块
A的构造函数
B的构造代码块
B的构造函数

由上我们可以得出的结论:

1执行静态代码块,2执行构造代码块,3执行构造函数。

2对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。

3当有继承时的执行顺序 :a)执行父类的静态代码块,并初始化父类静态成员变量;b)执行子类的静态代码块,并初始化子类静态成员变量;c)执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量;d)执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量;如下图:



来源: http://www.cnblogs.com/Qian123/p/5713440.html













猜你喜欢

转载自blog.csdn.net/wanghang88/article/details/80119342