欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

new一个对象的初始化过程

程序员文章站 2022-05-18 20:17:15
############################### 今天总结一下,new对象的初始化过程。 ############################### 首先,当不含static成员时,先看一下案例图: 如图所示,我们先定义相关类,Building,House(继承Building), ......

###############################

今天总结一下,new对象的初始化过程。

###############################

首先,当不含static成员时,先看一下案例图:

new一个对象的初始化过程

如图所示,我们先定义相关类,building,house(继承building),villa(继承house),同时,house有成员变量livingroom,livingroom有成员变量bed和desk。

具体代码实现如下:

 1 //建筑
 2 class building {
 3     public building() {
 4         system.out.println("building");
 5     }
 6 }
 7 //房子
 8 class house extends building{
 9     public livingroom livingroom = new livingroom();//卧室
10     public house() {
11         system.out.println("house");
12     }
13 } 
14 //别墅
15 class villa extends house{
16     public villa () {
17         system.out.println("villa");
18     }
19 }
20 //卧室
21 class livingroom {
22     public bed bedfirst = new bed();//床
23     public desk deskfirst = new desk();//桌子
24     
25     public livingroom () {
26         system.out.println("livingroom");
27     }
28 }
29 //床
30 class bed {
31     public bed () {
32         system.out.println("bed");
33     }
34 }
35 //桌子
36 class desk {
37     public desk () {
38         system.out.println("desk");
39     }
40 }
41 此时,我们new villa():
42 public class initializedemo {
43     @test
44     public void testinitialize() {
45         villa villa = new villa();
46     }
47 }
48 执行结果为:
49 building
50 bed
51 desk
52 livingroom
53 house
54 villa

 

  在此案例中,我们在创建villa对象时,会先试着创建villa的父类house的对象,但house也有父类building,building还有父类object。因此,实际上,本类会先创建object对象并初始化,在object对象创建并初始化后,会创建building对象,building对象没有成员变量,所以直接执行构造器,打印出building。

  接着,开始创建house对象,house对象有成员变量livingroom,因此,会先初始化livingroom,创建livingroom时,也会先创建livingroom的父类object对象并初始化没其次再创建livingroom实例,livingroom同样有两个成员变量bed和desk,因而会按两个成员变量的定义顺序,先后创建bed和desk。初始化成员变量成功后,执行livingroom的构造器,打印livingroom。初始化livingroom成功后,开始执行house的构造器,打印house。

  最后,在house初始化成功后,执行了villa的构造器,打印出villa。

  初始化成功。

其次,当有static成员时

 1 class family {
 2     family (class classname) {
 3         system.out.println("创建family对象");
 4         system.out.println(classname.getname());
 5     }
 6 }
 7 class person {
 8     person() {
 9         system.out.println("创建person对象");
10     }    
11     public static family family = new family(person.class);
12     static {
13         system.out.println("执行person静态代码块");
14     }
15     {
16         system.out.println("执行person代码块");
17     }
18 } 
19 public class student extends person {    
20 public student() {
21         system.out.println("创建student对象");
22     }
23     {
24         system.out.println("执行student代码块");
25     }
26     static {
27         system.out.println("执行student静态代码块");
28     }
29     public static family staticfamily = new family(student.class);
30     @test
31     public void test() {
32         system.out.println("=============");
33     }
34     public family family = new family(student.class);
35 }
36 执行结果:
37 创建family对象
38 com.tca.thinkinjava.chap7.person
39 执行person静态代码块
40 执行student静态代码块
41 创建family对象
42 com.tca.thinkinjava.chap7.student
43 执行person代码块
44 创建person对象
45 执行student代码块
46 创建family对象
47 com.tca.thinkinjava.chap7.student
48 创建student对象

 

  1.首先在执行@test方法时,必须创建student的实例对象。

  2.要创建student的实例对象,第一步先加载student父类person和student类的字节码,并对相关静态成员变量进行初始化,执行静态代码块。

  3.首先加载父类person字节码,静态成员变量public static family ,family优于静态代码块前声明,所以先对静态成员变量family进行初始化。创建family对象,打印“创建family对象”,“xxxxxx”。

  4.加载完person字节码后,再加载student字节码。静态代码块再静态成员public static family staticfamily之前声明,所以先执行静态代码块,打印“执行student静态代码块”,在进行成员变量初始化,执行“创建family对象”,“xxxxxxxxxx”。

  5.创建student父类person的实例对象,创建实例对象时,先进行非静态成员变量初始化和代码块的执行,在执行构造器方法。所以先打印“执行person代码块”,再打印“创建person对象”。父类对象创建和初始化完毕。

  6.创建子类对象student,先进行非静态成员变量初始化和代码块的执行,在执行构造方法。代码块的声明再非静态成员变量声明之前,所以先执行代码块,打印“执行student代码块”,再对family进行初始化,创建family对象,打印“创建family对象”,“xxxxxxxxxxx”。

  7.执行test测试方法。

 

总结:

  当不含static成员时,我们new一个对象a时,首先会先创建a类的父类b的实例对象,如果b类仍有c类,会先创建父类c的对象,以此类推,是一个递归创建的过程;当该类的父类对象已经全部创建并初始化时,会对该类进行创建和初始化。但在对该类进行初始化时,会先初始该类对象的成员变量,再执行该类的构造方法。成员变量的初始化和代码块的执行顺序,由它们声明顺序决定的,按顺序依次初始化或执行,但均在构造器方法之前执行。

  当有static成员时,在该类第一次被jvm加载时,静态成员变量只会被初始化一次,静态代码块只会被执行一次。会先加载父类字节码,再加载子类字节码,如果有创建某类的实例对象,也是在该类的父类和该类的字节码加载完成之后,才会实例化该类父类的实例对象和该类的实例对象。静态成员变量的初始化和静态代码块的执行顺序,是由它们的声明顺序决定的,按顺序依次初始化或执行。