zoukankan      html  css  js  c++  java
  • Java初始化顺序(静态变量、静态初始化块、实例变量、实例初始化块、构造方法)

    1、执行顺序

    1.1、一个类中的初始化顺序

    类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

    1.2、两个具有继承关系类的初始化顺序

    父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

    示例如下:(结果见注释)

     1 class A {
     2     public A() {
     3         System.out.println("Constructor A.");
     4     }
     5 
     6     {
     7         System.out.println("Instance Block A.");
     8     }
     9     static {
    10         System.out.println("Static Block A.");
    11     }
    12 
    13     public static void main(String[] args) {
    14         new A();/*
    15                  * Static Block A. Instance Block A. Constructor A.
    16                  */
    17     }
    18 }
    19 
    20 class B extends A {
    21     public B() {
    22         System.out.println("Constructor B.");
    23     }
    24 
    25     {
    26         System.out.println("Instance Block B.");
    27     }
    28     static {
    29         System.out.println("Static Block B.");
    30     }
    31 
    32     public static void main(String[] args) {
    33         new A();/*
    34                  * Static Block A. Static Block B. Instance Block A. Constructor A.
    35                  */
    36         System.out.println();
    37         new B();/*
    38                  * Instance Block A. Constructor A. Instance Block B. Constructor B.
    39                  */// 静态成员和静态初始化块只会执行一次。
    40     }
    41 }

    2、对变量值的影响

    一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定?按1节中所述的执行顺序确定。

    这里考虑初始化块在变量定义之前的情形,此时会造成迷惑。

    初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。如:

    1     static {
    2         a = 3;
    3         // int b=a;//Cannot reference a field before it is defined
    4         // System.out.println(a);//Cannot reference a field before it is defined
    5     }
    6     static int a = 1;

    “对变量值的影响”是指 对变量赋值的初始化块位于变量定义之前 时,变量的最终值根据变量定义时是否显示初始化而会有不同结果(若初始化块位于变量定义之后,那么变量的值显然很容易就确定了,不会造成迷惑)。如:

     1 class Test {
     2     static {
     3         a = 3;
     4         // int b=a;//Cannot reference a field before it is defined
     5         // System.out.println(a);//Cannot reference a field before it is defined
     6         b = 3;
     7     }
     8     static int a = 1;
     9     static int b;
    10 
    11     public static void main(String[] args) {
    12         System.out.println(a);//1
    13         System.out.println(b);//3
    14     }
    15 }

    判断方法:

    显示初始化内部隐含 定义变量和对变量进行赋值的初始化块两部分,所以初始化块和显示初始化哪个在后变量的最终值就是该值。

    更多示例:

    1:

     1 class C {
     2 
     3     static {
     4         a = 2;
     5         b = 2;
     6     }
     7     static int a;
     8     static int b = 1;
     9 
    10     public C() {
    11         e = 3;
    12     }
    13 
    14     {
    15         c = 2;
    16         d = 2;
    17         e = 2;
    18     }
    19     int c;
    20     int d = 1;
    21     int e = 1;
    22 
    23     public static void main(String[] args) {
    24         System.out.println(C.a);//2
    25         System.out.println(C.b);//1
    26         System.out.println(new C().c);//2
    27         System.out.println(new C().d);//1
    28         System.out.println(new C().e);//3
    29     }

    2:

     1 class C {
     2     public C() {
     3     }
     4 
     5     {
     6         a = 3;
     7     }
     8     static {
     9         a = 2;
    10     }
    11     static int a;
    12     static int b;
    13 
    14     public static void main(String[] args) {
    15         System.out.println(C.a);// 2
    16         System.out.println(new C().a);// 3
    17         System.out.println(C.b);// 0
    18     }
    19 }

    3:

     1 class C {
     2     // 以下关于静态初始化的
     3     static {
     4         a = 2;
     5     }
     6     static int a = 1;
     7     static int b = 1;
     8     static {
     9         b = 2;
    10         c = 2;
    11     }
    12     static int c;
    13 
    14     {
    15         d = 2;
    16     }
    17     int d = 1;
    18     int e = 1;
    19     {
    20         e = 2;
    21         f = 2;
    22     }
    23     int f;
    24 
    25     public static void main(String[] args) {
    26         System.out.println(C.a);// 1
    27         System.out.println(C.b);// 2
    28         System.out.println(new C().c);// 2
    29         System.out.println(new C().d);// 1
    30         System.out.println(new C().e);// 2
    31         System.out.println(new C().f);// 2
    32     }
    33 }

     3、总结

    执行顺序:

    1、类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

    2、父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

    初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。

    变量最终值:一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定:

    1、按执行顺序

    2、若对变量赋值的初始化块在变量定义前时:若变量显示初始化了则最终为显示初始化值,否则为初始化块的赋值。

    :凡事总有例外,实例初始化也可能位于类静态初始化前,示例:

    public class StaticTest {
    
        public static void main(String[] args) {
            staticFunction();
        }
    
        static StaticTest st = new StaticTest();
    
        static {
            System.out.println("1");
        }
    
        {
            System.out.println("2");
        }
    
        StaticTest() {
            System.out.println("3");
            System.out.println("a=" + a + ",b=" + b);
        }
    
        public static void staticFunction() {
            System.out.println("4");
        }
    
        int a = 110;
        static int b = 112;
    }
    
    结果如下:
    2
    3
    a=110,b=0
    1
    4
  • 相关阅读:
    BZOJ4975: [Lydsy1708月赛]区间翻转( 博弈&逆序对)
    BZOJ4550: 小奇的博弈(NIMK博弈& 组合数& DP)
    BZOJ5301: [Cqoi2018]异或序列(莫队)
    BZOJ5450: 轰炸(水题,Tarjan缩点求最长路)
    BZOJ5125: [Lydsy1712月赛]小Q的书架(DP决策单调性)
    codevs 2495 水叮当的舞步
    bzoj 1086: [SCOI2005]王室联邦
    bzoj 3720: Gty的妹子树
    bzoj 1024: [SCOI2009]生日快乐
    bzoj 1085: [SCOI2005]骑士精神
  • 原文地址:https://www.cnblogs.com/z-sm/p/6973993.html
Copyright © 2011-2022 走看看