前置回顾:上一节我们学习了封装、private、get/set 方法,知道了要把成员变量私有化,对外提供访问入口。 思考一个问题:对象创建的时候,能不能直接给成员变量赋值,而不是创建对象后再调用set方法?这就是构造方法要解决的问题。
一、什么是构造方法
构造方法(Constructor),也叫构造器,专门在创建对象的时候自动调用,用来给对象初始化数据。
✅ 核心特点(硬性语法规则,一定要记牢)
- 方法名必须和类名完全一致,大小写都不能错
- 没有返回值类型 ,连
void都不能写! - 只有在
new创建对象的时候自动执行,不能手动通过对象名调用 - 一个类可以同时拥有多个构造方法,构成构造重载
误区提醒: 很多新手会写成
public void Student(){},带了void,它就不再是构造方法,只是一个普通成员方法,new对象的时候不会自动执行!
二、默认无参构造
如果我们写一个类,没有手动写任何构造方法,编译器会自动帮我们生成一个【默认无参构造】。
示例代码:
java
class Student{
// 成员变量
private String name;
private int age;
// 这里我们没有写构造方法
// 编译后,自动隐藏生成:public Student(){}
// get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
// 调用默认无参构造创建对象
Student s1 = new Student();
s1.setName("张三");
s1.setAge(18);
System.out.println(s1.getName() + "," + s1.getAge());
}
}
⚠️ 重要规则: 只要手动写了任意一个构造方法(比如有参构造),编译器就不再提供默认无参构造! 这个是高频踩坑点,后面开发经常报错 找不到符号 构造方法 Student(),基本都是这个原因。
三、有参构造方法
有参构造,就是带有参数列表的构造器,作用:创建对象的同时,直接给成员变量赋值,简化代码。
java
class Student{
private String name;
private int age;
// 有参构造
public Student(String name, int age){
// 局部变量name,和成员变量name重名,this区分
this.name = name;
this.age = age;
}
// get、set
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
// new的时候直接传参,调用有参构造
Student s2 = new Student("李四", 20);
System.out.println(s2.getName() + "," + s2.getAge());
// 报错!因为我们手写了有参构造,默认无参构造消失了
// Student s1 = new Student();
}
}
四、标准写法:无参 + 有参构造一起写
在企业开发、写实体类(Javabean)时,规范写法:手动同时写出无参构造 + 全参构造,避免后续框架(MyBatis、Spring)报错。
完整标准实体类示例:
java
class Student{
// 1.私有化成员变量
private String name;
private int age;
// 2.无参构造
public Student(){
// 可以在这里写初始化逻辑,比如默认值
System.out.println("无参构造执行了");
}
// 3.全参构造
public Student(String name, int age){
System.out.println("有参构造执行了");
this.name = name;
this.age = age;
}
// 4.getter & setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("王五");
s1.setAge(19);
Student s2 = new Student("赵六", 21);
System.out.println(s1.getName() + "---" + s1.getAge());
System.out.println(s2.getName() + "---" + s2.getAge());
}
}
运行结果:
java
无参构造执行了
有参构造执行了
王五---19
赵六---21
五、构造方法重载
构造方法也支持重载,满足不同场景初始化需求:
- 无参构造:创建空对象,后续用set赋值
- 单参构造:只初始化名字
- 全参构造:一次性初始化所有属性
java
public Student(){}
public Student(String name){
this.name = name;
}
public Student(String name, int age){
this.name = name;
this.age = age;
}
重载判断标准:方法名相同,参数列表不同(个数、类型、顺序),和返回值无关(构造本来就没有返回值)
六、this() 在构造方法中调用其他构造
在一个构造方法内部,可以使用 this(参数) 调用本类中其他的构造方法。 ✅ 规则:
this()必须写在构造方法第一行- 不能互相循环调用(A构造调用B,B又调用A,直接报错)
- 只能在构造方法里使用,普通方法不能写this()
示例:
java
public Student(){
// 调用本类的全参构造,固定默认年龄18
this("匿名",18);
}
public Student(String name, int age){
this.name = name;
this.age = age;
}
七、构造方法 vs 普通成员方法(对比总结)
| 对比项 | 构造方法 | 普通成员方法 |
|---|---|---|
| 方法名 | 和类名一模一样 | 自定义名字,见名知意 |
| 返回值 | 无,不能写void | 需要写返回值类型/void |
| 调用时机 | new对象时自动调用 | 对象.方法名()手动调用 |
| 作用 | 对象初始化,给成员变量赋初始值 | 封装业务逻辑、功能行为 |
| 重载 | 支持 | 支持 |
八、常见易错坑汇总
- ❌ 构造方法加了void,变成普通方法,new的时候不执行
- ❌ 写了有参构造之后,还想无参new,忘记手动补无参构造
- ❌ this() 没有放在构造方法第一行,编译报错
- ❌ 构造方法互相循环调用,栈溢出
- ❌ 试图用
对象.构造名()的方式手动调用构造方法
九、小结
- 构造器的核心使命:对象初始化,new的时候自动跑
- 不写构造,编译器赠送无参;手写任意构造,赠送的就消失
- 开发规范:实体类统一写上【无参构造 + 全参构造】
this(...)可以在构造内部复用其他构造代码,减少重复