【Java 语言】— 面向对象:构造方法(无参、有参构造)

前置回顾:上一节我们学习了封装、private、get/set 方法,知道了要把成员变量私有化,对外提供访问入口。 思考一个问题:对象创建的时候,能不能直接给成员变量赋值,而不是创建对象后再调用set方法?这就是构造方法要解决的问题。

一、什么是构造方法

构造方法(Constructor),也叫构造器,专门在创建对象的时候自动调用,用来给对象初始化数据。

✅ 核心特点(硬性语法规则,一定要记牢)

  1. 方法名必须和类名完全一致,大小写都不能错
  2. 没有返回值类型 ,连 void 都不能写!
  3. 只有在 new 创建对象的时候自动执行,不能手动通过对象名调用
  4. 一个类可以同时拥有多个构造方法,构成构造重载

误区提醒: 很多新手会写成 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(参数) 调用本类中其他的构造方法。 ✅ 规则:

  1. this() 必须写在构造方法第一行
  2. 不能互相循环调用(A构造调用B,B又调用A,直接报错)
  3. 只能在构造方法里使用,普通方法不能写this()

示例:

java 复制代码
public Student(){
    // 调用本类的全参构造,固定默认年龄18
    this("匿名",18);
}
public Student(String name, int age){
    this.name = name;
    this.age = age;
}

七、构造方法 vs 普通成员方法(对比总结)

对比项 构造方法 普通成员方法
方法名 和类名一模一样 自定义名字,见名知意
返回值 无,不能写void 需要写返回值类型/void
调用时机 new对象时自动调用 对象.方法名()手动调用
作用 对象初始化,给成员变量赋初始值 封装业务逻辑、功能行为
重载 支持 支持

八、常见易错坑汇总

  1. ❌ 构造方法加了void,变成普通方法,new的时候不执行
  2. ❌ 写了有参构造之后,还想无参new,忘记手动补无参构造
  3. ❌ this() 没有放在构造方法第一行,编译报错
  4. ❌ 构造方法互相循环调用,栈溢出
  5. ❌ 试图用 对象.构造名() 的方式手动调用构造方法

九、小结

  1. 构造器的核心使命:对象初始化,new的时候自动跑
  2. 不写构造,编译器赠送无参;手写任意构造,赠送的就消失
  3. 开发规范:实体类统一写上【无参构造 + 全参构造】
  4. this(...) 可以在构造内部复用其他构造代码,减少重复
相关推荐
SimonKing1 小时前
素笺( local-notes)全面优化,新增功能体验不一样的笔记
java·后端·程序员
techpupil1 小时前
IDEA基础配置及开发基础插件
java·ide·intellij-idea
yuniko-n1 小时前
【JVM】对象内存布局
java·开发语言·jvm
何中应1 小时前
【Go-1】变量&常量定义
开发语言·后端·golang
CoderYanger1 小时前
Java EE 进阶:6.SpringBoot 配置文件(第二弹)
java·spring boot·spring·面试·职场和发展·java-ee·程序员创富
文丑颜不良啊1 小时前
LeetCode1681~1700题目解析
java·leetcode
愚农搬码1 小时前
电子表单、动态表单、表单设计器和表单引擎到底有什么区别?
java·后端
CarIise1 小时前
Spring 框架AOP与 XML 基础
java·开发语言
m0_639906941 小时前
SpringBoot 实现大模型统一调度网关|对接 OpenAI、Claude 协议差异与适配方案
java·spring boot·spring