分享

6.6 对象的初始化

 lifei_szdz 2012-12-26
6.6 对象的初始化
2012-10-30 14:51:51     我来说两句 
收藏    我要投稿   

当调用类的构造器来创建对象时,它将给新建的对象分配内存,并对对象进行初始化操作。现在我们来探讨对对象进行初始化操作时的细节。

对象的初始化操作将递归如下的步骤来进行:

(1)设置实例变量的值为默认的初始值 (0, false, null),不同的数据类型有不同的初始值。

(2)调用类的构造器(但是还没有执行构造方法体),绑定构造器参数。

(3)如果构造器中有this()调用,则根据this()调用的参数调用相应的重载构造器,然后转到步骤(5);否则转到步骤(4)。

(4)除java.lang.Object类外,调用父类中的初始化块初始化父类的属性,然后调用父类构造器,如果在构造器中有super()调用,则根据super()中的参数调用父类中相应的构造器。

(5)使用初始化程序和初始化块初始化成员。

(6)执行构造器方法体中的其他语句。

所谓的初始化块,就是我们在前面章节提到的所谓“游离块”。不管使用哪个构造器创建对象,它都会被首先运行,然后才是构造器的主体部分被执行。

我们来看一个例子。

源文件:TestPerson.java

class Person {
 private String name;

 private int age;

 private String sex;

 public Person() {
  System.out.println("构造器Person()被调用");
  sex = "Male";
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 public Person(String theName) {
  // 调用构造器Person()
  this();
  System.out.println("构造器Person(String theName)被调用");
  name = theName;
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 public Person(String theName, int theAge) {
  // 调用构造器Person(String theName)
  this(theName);
  System.out.println("构造器Person(String theName,int theAge)被调用");
  age = theAge;
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 // 初始化块
 {
  name = "Tony Blair";
  age = 50;
  sex = "Female";
  System.out.println("初始化块执行后:name=" + name
+ " , age=" + age + " ,sex=" + sex);
 }
}

public class TestPerson {
 public static void main(String[] args) {
  Person person = new Person();
 }
}

编译执行上面的程序,将会得到如下的输出:

初始化块执行后:name=Tony Blair ,age=50 ,sex=Female

构造器Person()被调用

name=Tony Blair ,age=50 ,sex=Male

可以看到,初始化块会先于构造器调用执行。读者可以将main()方法中调用的创建Person对象的构造器换成其他两个,再观察它的结果,同样可以得出上面的结论。

提示:

初始化块的机制并不是必须的,完全可以将属性的初始化和属性的声明结合在一起,例如:

    String name =  "Tony Blair";

下面看一个对象初始化的例子,以加深对对象初始化的理解:

源文件:Person.java

class Person {
 private String name;

 private int age;

 private String sex;

 public Person() {
  System.out.println("构造器Person()被调用");
  sex = "Male";
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 public Person(String theName) {
  System.out.println("构造器Person(String theName)被调用");
  name = theName;
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 public Person(String theName, int theAge) {
  System.out.println("构造器Person(String theName,int theAge)被调用");
  name = theName;
  age = theAge;
  System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
 }

 // 初始化块
 {
  name = "Tony Blair";
  age = 50;
  sex = "Female";
  System.out.println("Person初始化块执行后:name=" + name
 + " ,age=" + age + " ,sex=" + sex);
 }
}

这里定义了一个父类Person,它里面定义了3个构造器以及1个初始化块。

我们再来定义一个Person类的子类Teacher,代码如下。

源文件:Teacher.java

//Person子类
class Teacher extends Person {
 // 部门
 String department;

 // 教龄
 int schoolAge;

 public Teacher() {
  System.out.println("构造器Teacher()被调用");
 }

 public Teacher(String name) {
  // 调用父类中的构造器Person(String theName)
  super(name);
  System.out.println("构造器Teacher(String name)被调用");
 }

 public Teacher(int theSchoolAge) {
  schoolAge = theSchoolAge;
 }

 public Teacher(String dept, int theSchoolAge) {
  // 调用本类中重载的构造器Teacher(int theSchoolAge)
  this(theSchoolAge);
  department = dept;
 }

 // 初始化块
 {
  department = "教务部";
  System.out.println("Teacher初始化块执行后:name=" + name + " ,age=" + age+ " ,sex=" + sex);
 }
}

这个类中定义了4个构造器:一个不带参数的构造器;一个带一个String数据类型参数的构造器,它通过super()显式调用父类的构造器;一个带一个int数据类型参数的构造器;一个带两个参数的构造器,通过this()来调用类中带int类型参数的构造器。

最后我们来看测试程序。

源文件:TestInit.java

public class TestInit {
 public static void main(String[] args) {
  System.out.println("------------------------------------");
  Teacher t1 = new Teacher();
  System.out.println("");

  System.out.println("------------------------------------");
  Teacher t2 = new Teacher("Tom");
  System.out.println("");

  System.out.println("------------------------------------");
  Teacher t3 = new Teacher("财务部", 20);
 }
}

这个程序通过3种构造器来创建3个Teacher对象,因为调用的构造器不同,所以对象初始化的步骤也有所不同。因为在这几个程序中,几个关键部分都已经有信息打印到控制台,所以,只要执行这个程序,就可以看出各个调用构造器创建对象的运行细节。

编译并运行TestInit,可以在控制台上得到如下的信息:

------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person()被调用
name=Tony Blair ,age=50 ,sex=Male
Teacher初始化块执行后:name=Tony Blair ,age=50 ,sex=Male
构造器Teacher()被调用

------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person(String theName)被调用
name=Tom ,age=50 ,sex=Female
Teacher初始化块执行后:name=Tom ,age=50 ,sex=Female
构造器Teacher(String name)被调用

------------------------------------
Person初始化块执行后:name=Tony Blair ,age=50 ,sex=Female
构造器Person()被调用
name=Tony Blair ,age=50 ,sex=Male
Teacher初始化块执行后:name=Tony Blair ,age=50 ,sex=Male

请读者参考上面列出的对象初始化的6个步骤和本程序的执行结果,充分理解和掌握对象初始化的过程。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多