黑马程序员----------通过一个题分析类的创建过程

                                   ----------------------android培训java培训、期待与您交流! ----------------------

通过下面一道题来分析一下一个类的创建过程。

写出运行结果:

class ClassA{ 

static { 

System.out.println("In ClassA Static"); 

} 

public ClassA(){ 

System.out.println("ClassA()"); 

} 

} 

class ClassB{ 

static { 

System.out.println("In ClassB Static"); 

} 

public ClassB(){ 

System.out.println("ClassB()"); 

} 

} 

class ClassC extends ClassB{ 

static{ 

System.out.println("In ClassC Static"); 

} 

public ClassC(){ 

System.out.println("ClassC()"); 

 

} 

} 

class MyClass { 

static ClassA ca = new ClassA(); 

ClassC cc = new ClassC(); 

static{ 

System.out.println("In MyClass Static"); 

} 

public MyClass(){ 

System.out.println("MyClass()"); 

} 

} 

public class TestMain{ 

public static void main(String args[]){ 

MyClass mc1 = new MyClass(); 

MyClass mc2 = new MyClass(); 

System.out.println(mc1.cc == mc2.cc); 

System.out.println(mc1.ca == mc2.ca); 

} 

} 

分析:

该题需要创建两个MyClass 对象。

一般而言,创建对象的过程如下:

1) 分配空间

2) 递归构造父类对象

3) 初始化本类属性

4) 调用本类构造方法

如果某个类是JVM 运行中第一次遇到,则会进行类加载的动作。类加载会初始化该类

的静态属性,并执行该类的静态初始化代码块。

因此,本题中创建的两个MyClass 对象,依次会进行如下步骤:

1) 加载MyClass 类,并初始化其静态属性

2) 为MyClass 分配空间

3) 递归构造MyClass 的父类对象。

4) 初始化MyClass 属性

5) 调用MyClass 的构造方法。

至此,第一个对象创建完成。之后创建第二个对象时,由于类加载已经完成,因此跳过

类加载的步骤,即:

6) 为MyClass 分配空间

7) 递归构造MyClass 的父类对象

8) 初始化MyClass 属性

9) 调用MyClass 的构造方法。

经过9 个步骤,两个对象创建完毕。

其中,在第1 步时,类加载时会初始化其静态属性,之后会执行静态初始化代码块,因

此对第1 步进行细分:

1.1 初始化ca 属性

1.2 执行MyClass 的静态初始化代码块。

在1.1 执行时,初始化ca 属性会创建ClassA 对象。由于这是第一次在程序中用到ClassA

对象,因此会执行对ClassA 对象的类加载。即:1.1 步可以细分为以下步骤:

1.1.1 加载ClassA 类

1.1.2 创建ClassA 对象

在初始化MyClass 属性时,需要创建ClassC 对象。而程序执行到第4 步时是第一次遇

到ClassC 类型的对象,因此会执行ClassC 的类加载。因此,对第4 步和第8 步进行细化:

第4 步:初始化MyClass 属性:

4.1 加载ClassC

4.2 为ClassC 分配空间

4.3 递归构造ClassC 的父类对象

4.4 初始化ClassC 属性

4.5 调用ClassC 的构造方法

第8 步,初始化MyClass 属性:

8.1 为ClassC 分配空间

8.2 递归构造ClassC 的父类对象

8.3 初始化ClassC 属性

8.4 调用ClassC 的构造方法

对于4.1 而言,为了创建ClassC 对象,必须获取ClassC 类的信息。而获得ClassC 类完

整信息的前提,是获得ClassB 类的信息。由于是第一次遇到ClassB 和ClassC,因此会先加

载ClassB,之后加载ClassC。细分之后,4.1 分为以下两步:

4.1.1 加载ClassB

4.1.2 加载ClassC

完整列出所有步骤如下:

1.1.1 加载ClassA 类  输出In ClassA Static

1.1.2 创建ClassA 对象  输出ClassA()

1.2 执行MyClass 的静态初始化代码块  输出In Static MyClass

2 分配MyClass 的空间  无输出

3 递归构造MyClass 的父类对象  无输出

4.1.1 加载ClassB  输出 In ClassB Static

4.1.2 加载ClassC  输出In ClassC Static

4.2 分配ClassC 的空间  无输出

4.3 构造ClassC 的父类对象(ClassB)  输出ClassB()

4.4 初始化ClassC 属性  无输出

4.5 调用ClassC 的构造方法  输出ClassC()

5 调用MyClass 的构造方法  输出MyClass()

6 为MyClass 分配空间  无输出

7 递归构造MyClass 的父类对象  无输出

8.1 为ClassC 分配空间  无输出

8.2 递归构造ClassC 的父类对象  ClassB()

8.3 初始化ClassC 的属性  无输出

8.4 调用ClassC 的构造方法  ClassC()

9 调用MyClass 的构造方法  MyClass()

运行结果:

In ClassA Static

ClassA()

In Static MyClass

In ClassB Static

In ClassC Static

ClassB()

ClassC()

MyClass()

ClassB()

ClassC()

MyClass()

总结:

一个类的创建过程:

可以简单的分为一下几步:

1、加载本类

2、分配内存空间

3、递归调用父类构造方法

4、递归为父类分配空间

5、递归初始化父类属性

6、递归创建父类对象

7、创建子类对象

执行顺序:静态成员变量--->静态代码块--->成员变量--->代码块

注意:静态成员变量和静态代码块只在类加载的时候执行一次,以后再创建对象不再执行。


                               ----------------------android培训java培训、期待与您交流! ----------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值