对象初始化过程细节

 

1.创建对象过程

 1  static{
 2                   静态代码块中的执行语句
 3          }
 4          
 5 特点:随着类的加载而执行,只执行一次并优先于主函数。 用于给类进行初始化。
 6 
 7 Persong   p  = new  Person("XX",XX);
 8 
 9 这句话执行了:
10    <1> 因为new用到了Person.class,所以会先找到Persong.class文件并加载到内存中
11    <2> 执行该类中的static代码块,如果有的话,给Person.class类进行初始化
12    <3> 在堆内存中开辟空间,分配内存地址
13    <4> 在堆内存中建立对象特有属性,并进行默认初始化
14    <5> 对属性进行初始化
15    <6> 对对象进行构造代码块初始化
16    <7> 对对象进行对应的构造函数初始化
17    <8> 将内存地址赋给栈内存中的p变量
18    

2.父子间对象初始化过程

 1 对象的初始化顺序:
 2 
 3   1.首先执行父类静态的内容,父类静态的内容执行完毕后;
 4   2.接着去执行子类的静态的内容,当子类的静态内容执行完毕之后;
 5   3.再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕;
 6   4.接着执行父类的构造方法,父类的构造方法执行完毕之后;
 7   5.它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块,子类的非静态代码块执行完毕;
 8   6.去执行子类的构造方法。
 9   
10   总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,
11   然后执行子类非静态代码块和构造方法。
12 
13 注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。
14 如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
15    

 

  代码演示:

 1 class Father
 2 {
 3     int nonFatherStaticVar = nonFatherStaticShow();//父类非静态变量
 4     static int father = FatherStaticShow();//父类静态变量
 5     static //父类静态代码块
 6     {
 7         System.out.println("父亲的static代码块运行了");
 8     }
 9     public int nonFatherStaticShow(){
10         System.out.println("父类非静态变量初始化");
11         return 1;
12     }
13     public static int FatherStaticShow(){
14         System.out.println("父类静态变量初始化");
15         return 2;
16     }
17     public Father()//父类构造方法
18     {
19         System.out.println("父亲的构造函数运行了");
20     }
21     static void show(){
22         System.out.println("父亲普通方法运行了");
23     }
24     
25 }
26 class Son extends Father
27 {    
28     int nonSonStaticVar = nonSonStaticShow();//子类非静态变量
29     static int son = SonStaticShow();//子类静态变量
30     static //子类静态代码块
31     {
32         System.out.println("子类的static代码块运行了");
33     }
34     public int nonSonStaticShow(){
35         System.out.println("子类非静态变量初始化");
36         return 1;
37     }
38     public static int SonStaticShow(){
39         System.out.println("子类静态变量初始化");
40         return 2;
41     }
42     public Son()//父类构造方法
43     {
44         System.out.println("子类的构造函数运行了");
45     }
46     
47 }
48 
49 public class InitDemo
50 {    
51     public static void main(String[] args)
52     {
53         Son son = new Son();
54         son.show();
55     }
56 }
57 
58 /*
59     继承中,父子类间的初始化顺序:
60     
61     1、父类的静态代码块和静态变量初始化
62     2、子类静态代码块和静态变量初始化
63     3、父类非静态变量初始化
64     4、父类构造函数运行
65     5、子类非静态变量初始化
66     6、子类的构造函数运行
67 */

 

3.静态代码块不是在类加载时被调用的,而是第一个实例对象被创建时才执行的

 1 /*
 2 需求:测试构造代码块、静态构造代码块的执行顺序。
 3 */
 4 
 5 class StaticCode1
 6 {
 7         static
 8         {
 9                 System.out.println("StaticCode1——————静态代码块"); 
10         }
11         {
12                 System.out.println("StaticCode1————————代码块"); 
13         }
14 }
15 
16 class StaticCode
17 {
18         static
19         {
20                 System.out.println("3。StaticCode*************静态代码块——————"); 
21         }
22         {
23                 System.out.println("StaticCode************代码块————————"); 
24         }
25 }
26 
27 class StaticCodeDemo
28 {
29         static
30         {
31                 System.out.println("1。StaticCodeDemo静态代码块1"); 
32         }
33         {
34                 System.out.println("StaticCodeDemo代码块"); 
35         }
36         public static void main(String[] args) 
37         {
38                 //连续创建两个StaticCode类的对象,静态代码块之执行一次,非静态代码块执行两次
39                 new StaticCode();
40                 new StaticCode();
41 
42                 //同一个类中有多个静态代码块,按由上到下顺序执行
43                 new StaticCodeDemo();
44 
45                 //StaticCode1类已经加载,但是代码块却没有运行;
46                 StaticCode1 code1=null;
47                 StaticCode1 code12;
48 
49                 System.out.println("over"); 
50         }
51         static
52         {
53                 System.out.println("2。StaticCodeDemo静态代码块2"); 
54         }
55 }

程序的运行是:先创建main函数所在类的对象然后才找到main函数执行。

 

 

 

 

posted @ 2013-04-21 15:01  hacket520  阅读(220)  评论(0编辑  收藏  举报