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

    2021-01-21 17:12:55
    1 无继承情况下的Java初始化顺序: class Sample { Sample(String s) { System.out.println(s); } Sample() { System.out.println(Sample默认构造函数被调用); } } class Test{ static Sample sam=new...
  • JAVA初始化顺序

    2018-01-17 18:36:00
    1 无继承情况下的JAVA初始化顺序 2 JAVA继承情况下的初始化顺序 无继承情况下的JAVA初始化顺序 1 classSample 2 { 3 Sample(String s) 4 { 5 System.out.println(s); 6 } 7 Sampl...

    主要内容:

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

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

    无继承情况下的JAVA初始化顺序

     1 class Sample
     2 {
     3       Sample(String s)
     4       {
     5             System.out.println(s);
     6       }
     7       Sample()
     8       {
     9             System.out.println("Sample默认构造函数被调用");
    10       }
    11 }
    12 class Test{
    13       static Sample sam=new Sample("静态成员sam初始化");
    14       Sample sam1=new Sample("sam1成员初始化");
    15       static{
    16             System.out.println("static块执行");
    17             if(sam==null)System.out.println("sam is null");
    18             sam=new Sample("静态块内初始化sam成员变量");
    19             }
    20       Test()
    21       {
    22             System.out.println("Test默认构造函数被调用");
    23       }
    24 }
    25 //主函数
    26  public static void  main(String  str[])
    27 {
    28      Test a=new Test();
    29  }
    View Code

    输出结果为:

    静态成员sam初始化     -----静态成员初始化

    static块执行          -----静态块被执行

    静态块内初始化sam成员变量 ----静态块执行

    sam1成员初始化      -----普通成员初始化

    Test默认构造函数被调用  -----构造函数执行

    由此可以得出结论:

    静态成员变量首先初始化(注意,Static可以看做一个静态成员,其执行顺序和其在类中申明的顺序有关)

    b 普通成员初始化

    c 执行构造函数。

     

    对于静态成员(static块可以看成普通的一个静态成员,其并不一定在类初始化时首先执行)和普通成员,其初始化顺序只与其在类定义中的顺序有关,和其他因素无关。

    例如下面的例子:

     1 class Test{
     2       static{
     3             System.out.println("static 块 1  执行");
     4             }
     5       static Sample staticSam1=new Sample("静态成员staticSam1初始化");
     6       Sample sam1=new Sample("sam1成员初始化");
     7       static Sample staticSam2=new Sample("静态成员staticSam2初始化");
     8       static{
     9             System.out.println("static 块 2  执行");
    10             }
    11       Test()
    12       {
    13             System.out.println("Test默认构造函数被调用");
    14       }
    15       Sample sam2=new Sample("sam2成员初始化");
    16 }
    View Code

    则结果为:

    static 块 1  执行

    静态成员staticSam1初始化

    静态成员staticSam2初始化

    static 块 2  执行 

                          --------静态成员

    sam1成员初始化

    sam2成员初始化

                          --------普通成员

    Test默认构造函数被调用

                          --------构造函数

    JAVA继承情况下的初始化顺序

     1 class Sample {
     2     Sample(String s) {
     3         System.out.println(s);
     4     }
     5 
     6     Sample() {
     7         System.out.println("Sample默认构造函数被调用");
     8     }
     9 }
    10 
    11 class Test {
    12     static {
    13         System.out.println("父类static 块 1  执行");
    14     }
    15 
    16     static Sample staticSam1 = new Sample("父类 静态成员staticSam1初始化");
    17     Sample sam1 = new Sample("父类 sam1成员初始化");
    18     static Sample staticSam2 = new Sample("父类 静态成员staticSam2初始化");
    19 
    20     static {
    21         System.out.println("父类 static 块 2  执行");
    22     }
    23 
    24     Test() {
    25         System.out.println("父类 Test默认构造函数被调用");
    26     }
    27 
    28     Sample sam2 = new Sample("父类 sam2成员初始化");
    29 }
    30 
    31 class TestSub extends Test {
    32     static Sample staticSamSub = new Sample("子类 静态成员staticSamSub初始化");
    33 
    34     TestSub() {
    35         System.out.println("子类 TestSub 默认构造函数被调用");
    36     }
    37 
    38     Sample sam1 = new Sample("子类 sam1成员初始化");
    39     static Sample staticSamSub1 = new Sample("子类 静态成员staticSamSub1初始化");
    40 
    41     static {
    42         System.out.println("子类 static 块  执行");
    43     }
    44 
    45     Sample sam2 = new Sample("子类 sam2成员初始化");
    46 }
    View Code

    执行结果:

    父类 static 块 1  执行

    父类 静态成员staticSam1初始化

    父类 静态成员staticSam2初始化

    父类 static 块 2  执行

                            --------父类静态成员初始化

    子类 静态成员staticSamSub初始化

    子类 静态成员staticSamSub1初始化

    子类 static 块  执行

                            -------子类静态成员初始化

    父类 sam1成员初始化

    父类 sam2成员初始化

    父类 Test默认构造函数被调用       

                            -------父类普通成员初始化和构造函数执行

    子类 sam1成员初始化

    子类 sam2成员初始化

    子类 TestSub 默认构造函数被调用

                            -------父类普通成员初始化和构造函数执行

    由此得出JAVA初始化顺序结论:

    1 继承体系的所有静态成员初始化(先父类,后子类)

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

    3 子类初始化(普通成员-->构造函数)

    JAVA初始化顺序如图:

     

    转载于:https://www.cnblogs.com/Wonderful-life217/p/8302601.html

    展开全文
  • java初始化顺序

    2014-02-10 13:41:00
    java初始化顺序

    java初始化顺序


















    展开全文
  • Java 初始化顺序

    2016-10-23 18:08:58
    Java 初始化顺序 1、初始化顺序  在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。例如: class ...

    Java 初始化顺序

    1、初始化顺序

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

    class Window {
    	Window(int marker) {
    		System.out.println("Window(" + marker+ ")");
    	}
    }
    class House {
    	Window w1 = new Window(1); // before constructor
    	
    	House() {
    		System.out.println("House()");
    		w2 = new Window(33);
    	}
    	
    	Window w2 = new Window(2); // after constructor
    	
    	void f() {
    		System.out.println("f()");
    	}
    	
    	Window w3 = new Window(3);
    }
    public class OrderOfInitialization {
    	public static void main(String[] args) {
    		House h = new House();
    		h.f();
    	}
    }

    结果为:

    Window(1)
    Window(2)
    Window(3)
    House()
    Window(33)
    f()

    在House类中,故意把几个Window对象的定义散布到各处,以证明它们全部会在调用构造器或者其它方法之前得到初始化。

    此外,w3在构造器内再次被初始化。

    由输出可见,w3这个引用会被初始化两次:一次在调用构造器前,一次在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。

    2、静态数据初始化

        无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本类型的标准初值;如果它是一个对象引用,那么它的默认初始化值就是null。
        如果想在定义处进行初始化,采取的方法与非静态数据没什么不同。
        要想了解静态存储区域是何时初始化的,就请看下面这个例子:
    class Bowl {
    	Bowl(int marker) {
    		System.out.println("Bowl(" + marker + ")");
    	}
    	
    	void f1(int marker) {
    		System.out.println("f1(" + marker + ")");
    	}
    }
    class Table {
    	static Bowl bowl1 = new Bowl(1);
    	
    	Table() {
    		System.out.println("Table()");
    		bowl1.f1(1);
    	}
    	
    	void f2(int marker) {
    		System.out.println("f2(" + marker + ")");
    	}
    	
    	static Bowl bowl2 = new Bowl(2);
    }
    class Cupboard {
    	Bowl bowl3 = new Bowl(3);
    	static Bowl bowl4 = new Bowl(4);
    	Cupboard() {
    		System.out.println("Cupboard()");
    		bowl4.f1(2);
    	}
    	
    	void f3(int marker) {
    		System.out.println("f3(" + marker + ")");
    	}
    	
    	static Bowl bowl5 = new Bowl(5);
    }
    public class StaticInitialization {
    	public static void main(String[] args) {
    		System.out.println("Creating new Cupboard() in main");
    		new Cupboard();
    		System.out.println("Creating new Cupboard() in main");
    		new Cupboard();
    		table.f2(1);
    		cupboard.f3(1);
    	}
    	static Table table = new Table();
    	static Cupboard cupboard = new Cupboard();
    }
    结果为:
    Bowl(1)
    Bowl(2)
    Table()
    f1(1)
    Bowl(4)
    Bowl(5)
    Bowl(3)
    Cupboard()
    f1(2)
    Creating new Cupboard() in main
    Bowl(3)
    Cupboard()
    f1(2)
    Creating new Cupboard() in main
    Bowl(3)
    Cupboard()
    f1(2)
    f2(1)
    f3(1)
        Bowl类使得看到类的创建,而Table类和Cupboard类在它们的类定义中加入了Bowl类型的静态数据成员。注意,在静态数据成员定义之前,Cupboard类先定义了一个Bowl类型的非静态数据成员b3。
        由输出可见,静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.b1或Table.b2,那么静态的Bowl b1和b2永远都不会被创建。只有在第一个Table对象被创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化。
    初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是"非静态"对象。从输出结果中可以观察到这一点。
    要执行main()(静态方法),必须加载StaticInitialization类,然后其静态域table和cupboard被初始化,这将导致它们对应的类也被加载,
    并且由于它们也都包含静态的Bowl对象,因此Bowl随后也被加载。这样,在这个特殊的程序中的所有类在main()开始之前就都被加载了。
    总结一下对象的创建过程,假设有个名为Dog的类:
    1. 即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
    2. 然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
    3. 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
    4. 这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被设置成了nul。
    5. 执行所有出现于字段定义处的初始化动作。
    6. 执行构造器。

    3、继承初始化

        了解包括继承在内的初始化全过程,以对所发生的一切有个全局性的把握,是很有益的。请看下例:
    class Insect {
    	private int i = 9;
    	protected int j;
    	
    	Insect() {
    		System.out.println("i = " + i + ", j = " + j);
    		j = 39;
    	}
    	
    	private static int x1 = printInt("static Insect.x1 initialized");
    			
    	static int printInt(String s) {
    		System.out.println(s);
    		return 47;
    	}
    }
    public class Beetle extends Insect{
    	private int k = printInt("Beetle.k initialized");
    	private static int x2 = printInt("static Beetle.x2 initialized");
    	public Beetle() {
    		System.out.println("k = " + k);
    		System.out.println("j = " + j);
     	}
    	public static void main(String[] args) {
    		System.out.println("Beetle constructor");
    		Beetle beetle =  new Beetle();
    	}
    }
        结果为:   
    static Insect.x1 initialized
    static Beetle.x2 initialized
    Beetle constructor
    i = 9, j = 0
    Beetle.k initialized
    k = 47
    j = 39
         在Beetle上运行Java时,所发生的第一件事情就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件之中)。在对它进行加载的过程中,编译器注意到它有一个基类(这是由关键字extends得知的),于是它继续进行加载。不管你是否打算产生一个该基类的对象,这都要发生。
        如果该基类还有其自身的基类,那么第二个基类就会被加载,如此类推。接下来,根基类中的static初始化(在此例中为Insect)即会被执行,然后是下一个导出类,以此类推。这种方法很重要,因为导出类的static初始化可能会依赖于基类成员能否被正确初始化。
        至此为止,必要的类都已加载完毕,对象就可以被创建了。首先,对象中所有的基本类型都会被设为默认值,对象引用被设为null--这是通过将对象内存设为二进制零值而一举生成的。然后,基类的构造器会被调用。在本例中,它是被自动调用的。但也可以用super来指定对基类构造器的调用。基类构造器和导出类的构造器一样,以相同的顺序来经历相同的过程。在基类构造器完成之后,实例变量按其次序被初始化。最后,构造器的其余部分被执行。









    展开全文
  • java 初始化顺序

    2016-03-22 23:15:22
    1 无继承情况下的Java初始化顺序: class Sample {  Sample(String s)  {  System.out.println(s);  }  Sample()  {  System.out.println("Sample默认构造函数被调用");  
    1  无继承情况下的Java初始化顺序:
    class Sample
    {
          Sample(String s)
          {
                System.out.println(s);
          }
          Sample()
          {
                System.out.println("Sample默认构造函数被调用");
          }
    }
    class Test{
          static Sample sam=new Sample("静态成员sam初始化");
          Sample sam1=new Sample("sam1成员初始化");
          static{
                System.out.println("static块执行");
                if(sam==null)System.out.println("sam is null");
                sam=new Sample("静态块内初始化sam成员变量");
                }
          Test()
          {
                System.out.println("Test默认构造函数被调用");
          }

    }
    //主函数
     public static void  main(String  str[])
    {

         Test a=new Test();

     }
    输出结果为:
    静态成员sam初始化     -----静态成员初始化
    static块执行          -----静态块被执行
    静态块内初始化sam成员变量 ----静态块执行
    sam1成员初始化      -----普通成员初始化
    Test默认构造函数被调用  -----构造函数执行


    由此可以得出结论:
    静态成员变量首先初始化(注意,Static可以看做一个静态成员,其执行顺序和其在类中申明的顺序有关)
    b 普通成员初始化
    c 执行构造函数。

    对于静态成员(static块可以看成普通的一个静态成员,其并不一定在类初始化时首先执行)和普通成员,其初始化顺序只与其在类定义中的顺序有关,和其他因素无关。
    例如下面的例子:


    class Test{
          static{
                System.out.println("static 块 1  执行");
                }
          static Sample staticSam1=new Sample("静态成员staticSam1初始化");
          Sample sam1=new Sample("sam1成员初始化");
          static Sample staticSam2=new Sample("静态成员staticSam2初始化");
          static{
                System.out.println("static 块 2  执行");
                }
          Test()
          {
                System.out.println("Test默认构造函数被调用");
          }
          Sample sam2=new Sample("sam2成员初始化");

    }


    则结果为:
    static 块 1  执行
    静态成员staticSam1初始化
    静态成员staticSam2初始化
    static 块 2  执行 
                          --------静态成员
    sam1成员初始化
    sam2成员初始化
                          --------普通成员
    Test默认构造函数被调用
                          --------构造函数


    2 Java继承情况下的初始化顺序:

    class Test{
          static{
                System.out.println("父类static 块 1  执行");
                }
          static Sample staticSam1=new Sample("父类 静态成员staticSam1初始化");
          Sample sam1=new Sample("父类 sam1成员初始化");
          static Sample staticSam2=new Sample("父类 静态成员staticSam2初始化");
          static{
                System.out.println("父类 static 块 2  执行");
                }
          Test()
          {
                System.out.println("父类 Test默认构造函数被调用");
          }
          Sample sam2=new Sample("父类 sam2成员初始化");

    }

    class TestSub extends Test
    {
          static Sample staticSamSub=new Sample("子类 静态成员staticSamSub初始化");
          TestSub()
          {
                System.out.println("子类 TestSub 默认构造函数被调用");
          }
          Sample sam1=new Sample("子类 sam1成员初始化");
          static Sample staticSamSub1=new Sample("子类 静态成员staticSamSub1初始化");
          
          static{System.out.println("子类 static 块  执行");}
          Sample sam2=new Sample("子类 sam2成员初始化");
    }

    执行结果:
    父类 static 块 1  执行
    父类 静态成员staticSam1初始化
    父类 静态成员staticSam2初始化
    父类 static 块 2  执行
                            --------父类静态成员初始化
    子类 静态成员staticSamSub初始化
    子类 静态成员staticSamSub1初始化
    子类 static 块  执行
                            -------子类静态成员初始化
    父类 sam1成员初始化
    父类 sam2成员初始化
    父类 Test默认构造函数被调用       
                            -------父类普通成员初始化和构造函数执行
    子类 sam1成员初始化
    子类 sam2成员初始化
    子类 TestSub 默认构造函数被调用
                            -------父类普通成员初始化和构造函数执行


    由此得出Java初始化顺序结论:
    1 继承体系的所有静态成员初始化(先父类,后子类)
    2 父类初始化完成(普通成员的初始化-->构造函数的调用)
    3 子类初始化(普通成员-->构造函数)


    Java初始化顺序如图:
    分类: Java&JVM
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,872
精华内容 3,148
关键字:

java初始化顺序

java 订阅