钩子
上篇末尾留了个悬念:new 的第 2 步"执行初始化"到底是什么?
先看一个真实痛点:用上篇的写法,造一个学生要三行——new、赋 name、赋 age。造 100 个学生就是 300 行,而且谁都有可能忘了赋值,于是"我叫null"满天飞。
能不能让对象一出生就把名字带好?能,这就是构造方法——对象的出生证明。
01 构造方法:长得很怪,但很有用
class Student {
String name;
int age;
// 构造方法:名字 = 类名,没有返回值
Student(String name, int age) {
this.name = name;
this.age = age;
}
void introduce() {
System.out.println("我叫" + name + ",今年" + age + "岁");
}
}
三个特征,缺一不可:
- 方法名和类名一模一样(包括大小写);
- 不写返回值类型——连 void 都不写,写了就不是构造方法(上一篇的问题①的坑);
- new 的时候自动执行,你调不了它,它只在出生那一刻跑一次。
Student s1 = new Student("张三", 20); // 出生即带名字,一行搞定
s1.introduce(); // 我叫张三,今年20岁

02 编译器偷偷送的那个构造方法
现在有个诡异的问题:第 14 篇我们明明没写任何构造方法,为什么 new Student() 也能编译通过?
因为编译器看你一张构造方法都没写,会偷偷送一个:Student() { }——空的、不干活的,专业名叫默认构造方法。
但注意"一张都没写"这个前提。一旦你自己写了任何一个构造方法,比如 Student(String name),编译器立刻收回赠送——这时 new Student() 直接编译报错:
错误: 无法将类 Student中的构造器 Student应用到给定类型;
需要: java.lang.String
找到: 没有参数
人话:图纸上的出生方式只有"带名字"一种,你却想无参出生,没有这种出厂设置。
这是新手高频报错,解法也简单:想让两种出生方式都可用,就都写出来——
03 构造方法也能重载
第 11 篇学的重载,在构造方法上照常生效:
Student() { // 无参出生:默认值
}
Student(String name) { // 只带名字
this.name = name;
}
Student(String name, int age) { // 带名字带年龄
this.name = name;
this.age = age;
}
三种构造方法,三种出生姿势,new 时传什么参数就命中哪个——和普通方法重载的匹配规则一模一样。
细心的话你会发现一个重复:每个构造方法里都在写 this.name = name。能不能只写一遍?能——答案就是下篇的主角 this,还顺便解锁 Java 的"链式调用"。
本文示例代码均已本地实测通过,可直接运行。
对应文件:ConstructorDemo.java
橙码酱,分享更有用的技术知识,助你成为更优秀的开发者。