Java 构造
从上一节可以看出,在多数情况下,初始化一个对象的最终步骤是去调用这个对象的构造方法。构造方法负责对象的初始化工作,为实例变量赋予合适的初始值。构造方法必须满足以下语法规则: <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

· 方法名必须与类名相同。

·  不要声明返回类型。

·  不能被 static final synchronized abstract native 修饰。构造方法不能被子类继承,所以用 final abstract 修饰没有意义。构造方法用于初始化一个新建的对象,所以用 static 修饰没有意义。多个线程不会同时创建内存地址相同的同一个对象,因此用 synchronized 修饰没有必要。此外, Java 语言不支持 native 类型的构造方法。

在以下 Sample 类中,具有 int 返回类型的 Sample(int x) 方法只是个普通的实例方法,不能作为构造方法。

public class Sample {

private int x;

public Sample() { // 不带参数的构造方法

this(1);

}

public Sample(int x) { // 带参数的构造方法

this.x=x;

}

public int Sample(int x) { // 不是构造方法

return x++;

}

}

以上例子尽管能编译通过,但是使实例方法和构造方法同名,不是好的编程习惯,容易引起混淆。例如以下 Mystery 类的 Mystery() 方法有 void 返回类型,因此是普通的实例方法。

public class Mystery {

private String s;

public void Mystery() { // 不是构造方法

s = "constructor";

}

void go() {

System.out.println(s);

}

public static void main(String[] args) {

Mystery m = new Mystery();

m.go();

}

}

以上程序的打印结果为 null 。因为用 new 语句创建 Mystery 实例时,调用的是 Mystery 类的默认构造方法,而不是以上有 void 返回类型的 Mystery() 方法。关于默认构造方法的概念,参见本章第<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /> 11.2.2 节(默认构造方法)。


11.2.1 重载构造方法

当通过 new 语句创建一个对象时,在不同的条件下,对象可能会有不同的初始化行为。例如对于公司新来的一个雇员,在一开始的时候,有可能他的姓名和年龄是未知的,也有可能仅仅他的姓名是已知的,也有可能姓名和年龄都是已知的。如果姓名是未知的,就暂且把姓名设为 无名氏 ,如果年龄是未知的,就暂且把年龄设为 -1

可通过重载构造方法来表达对象的多种初始化行为。例程 11-2 Employee 类的构造方法有 3 种重载形式。在一个类的多个构造方法中,可能会出现一些重复操作。为了提高代码的可重用性, Java 语言允许在一个构造方法中,用 this 语句来调用另一个构造方法。

例程 11-2 Employee.java

public class Employee {

private String name;

private int age;

/** 当雇员的姓名和年龄都已知,就调用此构造方法 */

public Employee(String name, int age) {

this.name = name;

this.age=age;

}

/** 当雇员的姓名已知而年龄未知,就调用此构造方法 */

public Employee(String name) {

this(name, -1);

}

/** 当雇员的姓名和年龄都未知,就调用此构造方法 */

public Employee() {

this( " 无名氏 " );

}

public void setName(String name){this.name=name; }

public String getName(){return name; }

public void setAge(int age){this.age=age;}

public int getAge(){return age;}

}

以下程序分别通过 3 个构造方法创建了 3 Employee 对象。

Employee zhangsan=new Employee(" 张三 ",25);

Employee lisi=new Employee(" 李四 ");

Employee someone=new Employee();

Employee(String name) 构造方法中, this(name,-1) 语句用于调用 Employee(String name,int age) 构造方法。在 Employee() 构造方法中, this(" 无名氏 ") 语句用于调用 Employee(String name) 构造方法。

this 语句来调用其他构造方法时,必须遵守以下语法规则。

l 假如在一个构造方法中使用了 this 语句,那么它必须作为构造方法的第一条语句(不考虑注释语句)。以下构造方法是非法的:

public Employee(){

String name=" 无名氏 ";

this(name); // 编译错误, this 语句必须作为第一条语句

}

l 只能在一个构造方法中用 this 语句来调用类的其他构造方法,而不能在实例方法中用 this 语句来调用类的其他构造方法。

l 只能用 this 语句来调用其他构造方法,而不能通过方法名来直接调用构造方法。以下对构造方法的调用方式是非法的:

public Employee() {

String name= " 无名氏 ";

Employee(name); // 编译错误,不能通过方法名来直接调用构造方法

}