java静态代码块,构造方法,构造代码块的执行先后顺序

Posted CUIYD_1989

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java静态代码块,构造方法,构造代码块的执行先后顺序相关的知识,希望对你有一定的参考价值。

1、执行顺序

静态代码块>构造代码块>构造方法

原因:

  • 静态代码块(static)在类加载的时候执行一次,是最早被执行的。
  • 构造代码块(内的部分)在每一次创建对象时执行,始终在构造方法前执行。
  • 构造方法在新建对象时调用( 就是new的时候 )。

注意:

  • 静态代码块在类加载的时候就执行,所以它的优先级高于入口main()方法。
  • 当三种形式不止一次出现,同优先级是按照先后顺序执行。

程序代码示例:

public class StaticTest 
    public static StaticTest t1 = new StaticTest();
    public static StaticTest t2 = new StaticTest();

    
        System.out.println("构造块");
    

    static 
        System.out.println("静态块");
    

    public static void main(String[] args) 
        StaticTest t = new StaticTest();
    

执行main方法打印结果:


为什么会出现这种打印结果?

拓展知识点:静态域

静态域:分为静态变量,静态方法,静态块。当执行到静态域时,按照静态域的顺序加载。并且静态域只在类的第一次加载时执行

注意:加载了静态域的一部分,这时候不能再加载另一个静态域了,静态域必须当成一个整体来看待,否则加载会错乱。比如上面的代码,有静态变量和静态代码块儿,当加载了静态变量后,就不能加载静态代码块儿了

根据代码执行顺序:

(1)执行程序入口main方法时,首先加载类StaticTest
注意:加载类时并不会调用构造块和构造方法,只有静态域会执行
(2)加载类StaticTest,执行静态域的第一个静态变量,StaticTest t1 = new StaticTest();,输出构造块和构造方法(空)。打印出构造块。
(3)由于每次new对象时,会执行一次构造块和构造方法,构造块总是在构造方法前执行,(当然,第一次new时,会先执行静态域,静态域〉构造块〉构造方法)所以执行StaticTest t1 = new StaticTest();时,执行了下面代码:

 	
        System.out.println("构造块");
    

(4)同理,StaticTest t1 = new StaticTest();加载完后,以此执行第二个静态变量StaticTest t2 = new StaticTest();,执行构造块代码块。
(5)执行static静态块,完成对整个静态域的加载
(6)最后,再执行main方法,new StaticTest();,执行构造块。

附加:代码中添加了构造方法

public class StaticTest 
    public static StaticTest t1 = new StaticTest();
    public static StaticTest t2 = new StaticTest();

    
        System.out.println("构造块");
    

    static 
        System.out.println("静态块");
    

    public StaticTest() 
        System.out.println("构造方法代码");
    

    public static void main(String[] args) 
        StaticTest t = new StaticTest();
    

执行main方法的打印结果:

总结:
1、每调用一次构造方法,则执行一次构造块
2、静态块只在类加载的时候加载一次
3、有多个静态变量或块时,按声明顺序加载


2、java中父类和子类代码执行顺序

父类和子类代码执行顺序:

父类静态代码块 =》 子类静态代码块 =》 父类代码块 =》 父类构造方法 =》 子类代码块 =》 子类构造方法


程序代码如下:
1、创建Father和Son类,让Son继承Father
2、编写Father和Son的代码

/**
 * 父类(抽象类)
 */
public abstract class Father 

    static 
        System.out.println("父类静态代码执行了");
    

    
        System.out.println("父类非静态代码执行了");
    

    public Father() 
        System.out.println("父类构造函数代码执行了");
    

    public static void main(String[] args) 
        Son son = new Son();
    

/**
 * 子类(具体类)
 */
public class Son extends Father 

    static 
        System.out.println("子类静态代码执行了");
    

    
        System.out.println("子类非静态代码执行了");
    

    public Son() 
        System.out.println("子类构造函数代码执行了");
    

打印结果:

注意:由于代码的执行顺序不同,经常通过执行顺序进行后端初始化


拓展链接:
java的static关键字

子类继承父类,那么各代码块的执行顺序为:

子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是:

  • 父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数

解析:

按照先后顺序:
1,静态先于非静态代码库执行(静态代码块随着类的加载而加载,初始化只执行一次)
2,父类先于子类
3,非静态代码块优于构造函数执行
 
-----------------------------------------------------------------------------------------------------------------------------
ArraryList 与linkedList的区别:
ArraryList:1.ArrayList是基于数组的,所以,具备随机访问特点;
                 2.ArrayList插入或删除一个元素的开销不是固定的。在插入时,如果索引正确,容量够,则直接插入,插入位置之后的都需要移动,如果容量不够,还得扩充容量,开销当然不一样。删除操作同理。
linkedList:1.也可以通过也支持随机访问,但却付出了一定的代价。在LinkedList中,如果想返回某个位置的元素,就是从前往后遍历。如下。很明显,LinkedLIst不支持高效的随机访问
                2.LinkedList是基于双链表的,增加是在尾部增加,增加和删除都只需要修改指针,不需要移动元素。
Node<E> node(int index) {
    // assert isElementIndex(index);
 
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

----------------------------------------------------------------------------------------------------------------------------

A :错误
default  String  s
变量不能被defalut修饰
 
B:正确
public  final  static  native  int  w( )
native修饰方法,native修饰的方法简单来说就是:一个Java方法调用了一个非Java代码的接口。
定义navtive方法时,并不提供实现体,因为其实现体是用非Java语言在外面实现的。native可以和任何修饰符连用,abstract除外。因为native暗示这个方法时有实现体的,而abstract却显式指明了这个方法没有实现体。
 
C:错误
abstract  double  d
   abstract修饰方法和类
 
D:错误
abstract  final  double  hyperbolicCosine( )
final修饰的方法不能被重写。而abstract定义的方法没有实现,必须被子类重写,明显不能一起使用。

以上是关于java静态代码块,构造方法,构造代码块的执行先后顺序的主要内容,如果未能解决你的问题,请参考以下文章

一文详解:Java中父子类静态块构造块构造方法成员变量之间的初始化先后顺序与执行先后顺序

子类继承父类,那么各代码块的执行顺序为:

java-普通代码块构造代码块和静态代码块的区别。

java 关于Java中静态代码块以及构造函数的执行先后顺序

java对象的初始化过程和创建对象的几种方式

Java中静态代码块构造代码块构造函数普通代码块(转载)