精华内容
下载资源
问答
  • 初始化顺序

    2013-08-22 16:00:44
    在类的内部,变量定义的先后顺序决定了初始化顺序。即使变量定义散布于方法定义之间, 它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。例如: //: c04:OrderOfInitialization.java // ...
    在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,
    它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。例如:


    //: c04:OrderOfInitialization.java
    // Demonstrates initialization order.
    import com.bruceeckel.simpletest.*; 


    // When the constructor is called to create a
    // Tag object, you'll see a message:
    class Tag {
      Tag(int marker) { 
        System.out.println("Tag(" + marker + ")");
      }
    }


    class Card { 
      Tag t1 = new Tag(1); // Before constructor
      Card() { 
    // Indicate we're in the constructor:
        System.out.println("Card()");
        t3 = new Tag(33); // Reinitialize t3
      }
      Tag t2 = new Tag(2); // After constructor
    void f() {
        System.out.println("f()");
      }
      Tag t3 = new Tag(3); // At end
    }


    public class OrderOfInitialization { 
    static Test monitor = new Test(); 
    public static void main(String[] args) { 
        Card t = new Card(); 
        t.f(); // Shows that construction is done
        monitor.expect(new String[] { 
    "Tag(1)",
    "Tag(2)",
    "Tag(3)",
    "Card()",
    "Tag(33)",
    "f()"
     
        });
      }
    } ///:~


    在 Card 类中,故意把几个 Tag 对象的定义散布到各处,以证明它们全都会在调用构造器或
    其它方法之前得到初始化。此外,t3 在构造器内再次被初始化。


    由输出可见,t3 这个引用会被初始化两次:一次在调用构造器前,一次在调用期间(第一次
    引用的对象将被丢弃,并作为垃圾回收)。试想,如果定义了一个重载的构造器,它没有初
    始化 t3;同时在 t3 的定义里也没有指定缺省值,那会产生什么后果呢?所以尽管这种方法

    似乎效率不高,但它的确能使初始化得到保证。


    展开全文
  • Java类的初始化顺序

    万次阅读 多人点赞 2018-07-05 10:03:23
    对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。初始化顺序图示:我们也可以通过下面的测试代码来验证这一点:...

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

    初始化顺序图示:




    我们也可以通过下面的测试代码来验证这一点:

    package com.trs.oop;
    
    /**
     * 类的初始化顺序
     * 静态变量->静态初始化块->变量->初始化块->构造器
     * @author xiayunan
     * @date   2018年7月5日
     *
     */
    public class InitialOrderTest {   
      
        // 静态变量 
      
        public static String staticField = "静态变量";
      
        // 变量 
        public String field = "变量";   
      
        // 静态初始化块 
        static {   
            System.out.println(staticField);   
            System.out.println("静态初始化块");   
        }   
      
        // 初始化块 
        {   
            System.out.println(field);   
            System.out.println("初始化块");   
        }   
      
        // 构造器 
        public InitialOrderTest() {   
            System.out.println("构造器");   
        }   
      
        public static void main(String[] args) {
            new InitialOrderTest();   
        }   
    } 

    运行结果:


    而对于继承的情况初始化顺序又会是怎么样的呢?请看下面示例代码:

    package com.trs.oop;
    
    /**
     * 有继承关系的类初始化顺序
     * @author xiayunan
     * @date   2018年7月5日
     *
     */
    class Parent {   
        // 静态变量 
        public static String p_StaticField = "父类--静态变量";
        protected int i = 1;
        protected int j = 8;
        // 变量 
        public String p_Field = "父类--变量";   
      
        // 静态初始化块 
        static {   
            System.out.println(p_StaticField);   
            System.out.println("父类--静态初始化块");   
        }   
      
        // 初始化块 
        {   
            System.out.println(p_Field);   
            System.out.println("父类--初始化块");   
        }   
      
        // 构造器 
        public Parent() {   
            System.out.println("父类--构造器"); 
            System.out.println("i=" + i + ", j=" + j);
            j = 9;
        }   
    }   
      
    public class SubClass extends Parent {
      
        // 静态变量 
        public static String s_StaticField = "子类--静态变量";
      
        // 变量 
        public String s_Field = "子类--变量";   
        
        // 静态初始化块 
        static {   
            System.out.println(s_StaticField);   
            System.out.println("子类--静态初始化块");   
        }   
        // 初始化块 
        {   
            System.out.println(s_Field);   
            System.out.println("子类--初始化块");   
        }   
      
        // 构造器 
        public SubClass() {   
            System.out.println("子类--构造器"); 
            System.out.println("i=" + i + ",j=" + j);
        }   
      
        // 程序入口 
        public static void main(String[] args) {
            new SubClass();   
        }   
    }  

    运行结果:


    现在,结果已经不言自明了。子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
    静态变量、静态初始化块,变量、初始化块初始化了顺序取决于它们在类中出现的先后顺序。
    执行过程分析

     (1)访问SubClass.main(),(这是一个static方法),于是装载器就会为你寻找已经编译的SubClass类的代码(也就是SubClass.class文件)。在装载的过程中,装载器注意到它有一个基类(也就是extends所要表示的意思),于是它再装载基类。不管你创不创建基类对象,这个过程总会发生。如果基类还有基类,那么第二个基类也会被装载,依此类推。


    (2)执行根基类的static初始化,然后是下一个派生类的static初始化,依此类推。这个顺序非常重要,因为派生类的“static初始化”有可能要依赖基类成员的正确初始化。


    (3)当所有必要的类都已经装载结束,开始执行main()方法体,并用new SubClass()创建对象。


    (4)类SubClass存在父类,则调用父类的构造函数,你可以使用super来指定调用哪个构造函数(也就是Beetle()构造函数所做的第一件事)。


    基类的构造过程以及构造顺序,同派生类的相同。首先基类中各个变量按照字面顺序进行初始化,然后执行基类的构造函数的其余部分。


    (5)对子类成员数据按照它们声明的顺序初始化,执行子类构造函数的其余部分。


    展开全文
  • java初始化顺序

    2017-10-26 16:50:10
    1.无继承情况下的java初始化顺序  a:静态成员变量首先初始化  b:普通成员的初始化  C:执行构造函数 2.继承情况下的java初始化顺序 a:集成体系的所有静态成员初始化(先父。。后子) b:父类初始...

    1.无继承情况下的java初始化顺序

      a:静态成员变量首先初始化

     b:普通成员的初始化

     C:执行构造函数



    2.继承情况下的java初始化顺序

    a:集成体系的所有静态成员初始化(先父。。后子)

    b:父类初始化完成(普通成员的初始化---》构造函数的调用)

    c:子类初始化(普通成员------》构造函数)




    1.首先初始化静态域是因为静态域是放在方法区和class对象在一起的。
    2.由于类加载的时候,会向上查找基类,因为子类的初始化依赖于基类首先初始化。所以会首先发生“基类->子类"顺序的类加载,类加载过程中,顺便完成了静态域的初始化。
    3.另外一条规则是初始化块和域的初始化按照声明的顺序进行。

    展开全文
  • 初始化顺序

    千次阅读 2019-08-06 21:11:32
    前言 Class类中有静态属性、代码块、非静态属性…等诸多元素时,如果不清楚各个元素的初始顺序,...初始化顺序 话不多说,直接上代码: class Display { public static int parentStaticField() { System.out.pr...

    前言

    Class类中有静态属性、代码块、非静态属性…等诸多元素时,如果不清楚各个元素的初始顺序,那么很有可能会写出一些匪夷所思的代码。正因为其如此重要,所以博主写了个例子,很容易就能知道他们的初始顺序

    初始化顺序

    话不多说,直接上代码:

    class Display {
        public static int parentStaticField() {
            System.out.println("父类静态字段");
            return 1;
        }
        public static int parentField() {
            System.out.println("父类普通字段");
            return 1;
        }
        public static int sonStaticField() {
            System.out.println("子类静态字段");
            return 1;
        }
        public static int sonField() {
            System.out.println("子类普通字段");
            return 1;
        }
    }
    
    class Parent {
        static {
            System.out.println("父类静态代码块");
        }
    
        {
            System.out.println("父类普通代码块");
        }
    
        public static int a = Display.parentStaticField();
    
        public int b = Display.parentField();
    
        static {
            System.out.println("父类静态代码块2");
        }
    
        public Parent() {
            System.out.println("父类构造函数");
        }
    
        {
            System.out.println("父类普通代码块2");
        }
    }
    
    class Son extends Parent {
        static {
            System.out.println("子类静态代码块");
        }
    
        {
            System.out.println("子类普通代码块");
        }
    
        public static int c = Display.sonStaticField();
    
        public int d = Display.sonField();
    
        static {
            System.out.println("子类静态代码块2");
        }
    
        public Son() {
            System.out.println("子类构造函数");
        }
    
        {
            System.out.println("子类普通代码块2");
        }
    }
    
    public class ClassInitialOrder {
    
        public static void main(String[] args) {
            new Son();
        }
    }
    

    输出结果:

    父类静态代码块
    父类静态字段
    父类静态代码块2
    子类静态代码块
    子类静态字段
    子类静态代码块2
    父类普通代码块
    父类普通字段
    父类普通代码块2
    父类构造函数
    子类普通代码块
    子类普通字段
    子类普通代码块2
    子类构造函数
    

    由此可以看出,类初始化顺序为:
    父类静态代码块/静态字段(按照定义顺序)=> 子类静态代码块/静态字段(按照定义顺序)=> 父类普通代码块/普通字段(按照定义顺序)=> 父类构造方法 => 子类普通代码块/普通字段(按照定义顺序)=> 子类构造函数

    总结

    需要注意的几点是:

    • 静态代码块和静态字段只执行一次(不管父类还是子类)
    • 静态代码比非静态代码先执行
    • 代码块和字段执行的优先级就是定义的顺序,或者说代码编写的顺序
    • 父类构造方法比子类普通代码块先执行

    注意了以上四点,类的初始化应该就不是问题了。

    展开全文
  • 变量初始化顺序

    千次阅读 2017-07-24 19:13:09
    class中变量初始化顺序取决于变量在类中的定义顺序,所有变量一定会在任何函数执行前先初始化(包括构造函数) static修饰的变量存放在heap中,静态变量只初始化一次,且static变量在non-static变量前初始化。...
  • Java类初始化顺序

    2019-03-04 09:43:49
    类的初始化顺序,如类的静态变量、成员变量、静态代码块、非静态代码块、构造器,及继承父类时,它们的初始化顺序都是怎样的,下面我通过例子来说明这个情况,以免被人误导。 示例1:测试单类的初始化顺序 public ...
  • JAVA类初始化顺序总结

    万次阅读 2018-09-27 23:16:24
    初始化顺序 首先来看下,当一个类从main入口方法,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序: public class ClassLoadTest { private static User user = new User(); static { ...
  • java类的初始化顺序 java类的初始化顺序常会出现在java的笔试和面试题中,本文将通过实践代码对java类的初始化顺序做个分析! 首先结论话语放前面,java类的初始化顺序依次如下: 1.父类静态成员和静态初始化快,按...
  • JAVA初始化顺序

    2015-01-30 11:52:42
    类的初始化顺序 即为 类的静态变量初始化和静态块的加载顺序(按出现的先后顺序排列)对象的初始化顺序 即为 1.类的非静态变量的初始化和非静态块的加载顺序(按出现的先后顺序)2.构造函数public class testStatic ...
  • 初始化列表初始化顺序

    千次阅读 2018-07-23 09:15:01
    初始化列表是按类中声明变量的先后顺序初始化,与初始化列表的顺序无关。   class Printer{ public: Printer(std::string name) {std::cout << name;} }; class Container{ public: ...
  • java程序初始化顺序

    2019-02-12 13:40:54
    按照成员变量的初始化顺序进行初始化。即使变量定义散布于方法定义之中,它们依然在任何方法(包括构造函数)调用前先进行初始化。 父类静态变量 父类静态代码块 子类静态变量 子类静态代码块 父类非静态变量 ...
  • C++的初始化顺序

    2016-09-03 22:18:14
    3、初始化列表的初始化顺序和列表顺序无关,只和类中的声明顺序有关。 几种情况必须在初始化列表中进行初始化 (1)类成员为const类型 (2)类成员为引用 (3)类成员没有默认构造函数的类的类型所以,下面函数...
  • Java成员变量初始化顺序

    千次阅读 2018-11-24 22:28:49
    Java中成员变量分为两类:1、类变量 2、实例变量 1、类变量初始化 ...1.2 初始化顺序 上述两种方式在程序中的排列顺序即为执行顺序 class ClassVarInit{ static int value=10; static{ value=10...
  • c#初始化顺序

    2015-08-02 19:08:12
    c#类的初始化顺序 类在初始化时的执行顺序,依次如下: 1: 子类静态变量 2: 子类静态构造函数 3: 子类非静态变量 4: 父类静态变量 5: 父类静态构造函数 6: 父类非静态变量 7: 父类构造函数 8: 子类构造函数
  • 初始化列表的初始化顺序

    千次阅读 2009-10-17 13:29:00
    一般,初始化的顺序无关紧要,然而,如果一个成员是根据其他成员而初始化,则成员的初始化顺序是至关重要的。class x { int i;//声明顺序是先i,后j,故初始化列表中,会先初始化i,在初始化j int j;public: x
  • Java初始化顺序

    2016-03-15 21:51:39
    很多人对Java程序初始化顺序充满疑惑,不知道是先执行初始化块还是先执行构造函数。这里给出结论:(执行顺序从上到下依次进行) 第一、父类静态块 第二、子类静态块 第三、父类块方法 第四、父类构造方法 第五、...
  • Kotlin实例初始化时,构造函数、成员变量、init块等的初始化顺序必须弄清楚,否则容易出bug: Example: open class Parent { private val a = println("Parent.a") constructor(arg: Unit=println("Parent ...
  • 通过构造方法依赖的方式,来控制有依赖关系的 bean 之间初始化顺序,但是需要注意循环依赖的问题 @DependsOn注解,来控制 bean 之间的实例顺序,需要注意的是 bean 的初始化方法调用顺序无法保证 通过注入方式 ...
  • 初始化列表初始化顺序和变量声明的顺序一致,和初始化中的顺序无关。这里的代码中i比j先声明,所以这里的初始化顺序应该是先用j对i初始化,然后再用k对j初始化。由于在对i初始化的时候j并没有被初始化...
  • Java程序的初始化顺序

    2017-08-25 11:41:18
    Java程序的初始化顺序
  • C++初始化顺序

    千次阅读 2016-03-29 13:48:54
    如下代码所示: class test { const int a; std:string str; object o; test():str(“df”),o(null),a(0) ... test():str(“df”),o(null),a(0) 即...它们会在构造函数正式调用前被调用,且他们的初始化顺序并不是根据

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,215
精华内容 10,886
关键字:

初始化顺序