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 
   不是构造方法 
    
   
 
  
return x++; 
    
   
 
  
} 
    
   
 
  
}


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

public class Mystery { 
    
   
 
  
private String s; 
    
   
 
  
public void 
   不是构造方法 
    
   
 
  
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); // 
   编译错误,不能通过方法名来直接调用构造方法 
    
   
 
  
}

转载于:https://blog.51cto.com/1988wlpznn/168514