创建实例的时候,我们经常需要同时初始化这个实例的字段,例如:
Person ming = new Person();
ming.setName("小明");
ming.setAge(12);
初始化对象实例需要3行代码,而且,如果忘了调用setName()
或者setAge()
,这个实例内部的状态就是不正确的。
这时,我们就需要构造方法。
class Person {
private String name;
private int age;
// 构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
由于构造方法是如此特殊,所以构造方法的名称就是类名。
构造方法的参数没有限制,在方法内部,也可以编写任意语句。
但是,和普通方法相比,构造方法没有返回值(也没有
void
),调用构造方法,必须用new
操作符 。
默认构造方法
是不是任何class
都有构造方法?是的。
那前面我们并没有为Person
类编写构造方法,为什么可以调用new Person()
?
原因是如果一个类没有定义构造方法,编译器会自动为我们生成一个默认构造方法,它没有参数,也没有执行语句,类似这样:
class Person {
public Person() {
}
}
要特别注意的是,如果我们自定义了一个构造方法,那么,编译器就不再自动创建默认构造方法
如果既要能使用带参数的构造方法,又想保留不带参数的构造方法,那么只能把两个构造方法都定义出来:
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Xiao Ming", 15); // 既可以调用带参数的构造方法
Person p2 = new Person(); // 也可以调用无参数构造方法
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
多构造方法
可以定义多个构造方法,在通过new
操作符调用的时候,编译器通过构造方法的参数数量、位置和类型自动区分:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
this.age = 12;
}
public Person() {
}
}
如果调用 new Person("Xiao Ming", 20);
,会自动匹配到构造方法 public Person(String, int)
。
如果调用 new Person("Xiao Ming");
,会自动匹配到构造方法 public Person(String)
。
如果调用 new Person();
,会自动匹配到构造方法 public Person()
。
一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。调用其他构造方法的语法是this(…)
:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this(name, 18); // 调用另一个构造方法Person(String, int)
}
public Person() {
this("Unnamed"); // 调用另一个构造方法Person(String)
}
}