Day11 | Java构造方法与构造器重载

60 阅读5分钟

Java的构造方法是创建对象时自动调用的特殊方法,​​用于初始化对象的初始状态​​。

一、构造方法

当你用new创建对象时,Java会立即调用构造方法,为对象初始化内部状态。它是对象诞生的第一道工序。

package com.lazy.snail.day11;

/**
 * @ClassName Snail
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/5/26 14:04
 * @Version 1.0
 */
public class Snail {
    public Snail() {
        System.out.println("蜗牛对象创建");
    }

    public static void main(String[] args) {
        Snail snail = new Snail();
    }
}

main方法中使用new创建蜗牛对象,当运行时,构造方法Snail()会自动调用,控制台输出“蜗牛对象创建”。

构造方法和普通方法的区别:

特性构造方法普通方法
命名规则必须与类名完全相同自定义
返回值不能有返回值类型(包括void)必须声明返回值类型
调用时机new 时自动触发需通过对象手动调用
能否被继承不可被子类继承可以被继承
static 修饰禁止使用允许使用

二、默认构造方法

当类中没有定义任何构造方法时,Java会默认添加一个无参构造方法:

package com.lazy.snail.day11;

/**
   * @ClassName Student 
   * @Description TODO
   * @Author lazysnail
   * @Date 2025/5/26 14:10
   * @Version 1.0
   */
public class Student {
    private String name;
    private int age;
}

Student中没有显示的定义任何方法。

但是通过IDEA插件jclasslib能够看出,存在一个方法,这个就是编译器自动帮我们添加的默认无参构造。

如果我们手动添加了一个构造方法,那么此前的默认构造也就不存在了。

package com.lazy.snail.day11;

/**
   * @ClassName Student 
   * @Description TODO
   * @Author lazysnail
   * @Date 2025/5/26 14:10
   * @Version 1.0
   */
public class Student {
    private String name;
    private int age;

    public Student(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Student student = new Student();
    }
}

上面的代码中,我们添加了一个含一个参数的构造方法。在main方法中再使用无参构造创建对象时,会报编译错误。

jclasslib一样可以看出差异:

三、构造器重载

通过参数列表不同的多个构造方法,实现多样化的初始化方式:

package com.lazy.snail.day11;

/**
   * @ClassName Student 
   * @Description TODO
   * @Author lazysnail
   * @Date 2025/5/26 14:10
   * @Version 1.0
   */
public class Student {
    private String name;
    private int age;

    public Student() {
        this("懒惰蜗牛", 28);
        System.out.println("无参构造");
    }

    public Student(String name) {
        this(name, 28);
        System.out.println("单参构造");
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("多参构造");
    }

    public static void main(String[] args) {
        new Student();
        new Student("懒惰蜗牛");
        new Student("懒惰蜗牛", 28);
    }
}

Student()是无参构造,方法内部通过this方法调用了多参构造Student(String name,int age)。

Student(String name)是单参构造,内部同样通过this方法调用了多参构造Student(String name,int age)。

有两个注意点:

  • this(...)必须放在构造方法第一行,JVM会进行检测。
  • 禁止构造方法之间的死循环调用(如A调用B,B又调用A)

四、继承中的构造方法

子类构造方法会默认调用父类无参构造方法(super()):

父类Animal:

package com.lazy.snail.day11;

/**
 * @ClassName Animal
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/5/26 14:31
 * @Version 1.0
 */
public class Animal {
    public Animal() {
        System.out.println("Animal的无参构造");
    }
}

子类Snail通过extends继承Animal:

package com.lazy.snail.day11;

/**
 * @ClassName Snail
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/5/26 14:04
 * @Version 1.0
 */
public class Snail extends Animal{
    public Snail() {
        // 这里实际隐含了一句代码:super();
        System.out.println("Snail的无参构造");
    }

    public static void main(String[] args) {
        Snail snail = new Snail();
    }
}

通过new创建Snail对象时,Animal的无参构造先被调用,随后调用Snail的无参构造。

在构造子类之前,实际隐含了一句代码super();,这就是触发父类构造的。

父类构造是子类的基础,如果父类都没完全初始化(构造),子类继承过去的东西就是残缺的,出大问题。

如果父类没有无参构造时,必须显示的调用父类的有参构造:

假设Animal类是这样的:

package com.lazy.snail.day11;

/**
 * @ClassName Animal
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/5/26 14:31
 * @Version 1.0
 */
public class Animal {
    public Animal(String type) {
        System.out.println("Animal的类型:" + type);
    }
}

Animal由于显示的定义了一个有参的构造方法,也就没有了默认的无参构造。

那么子类在构造之前,就需要显示的调用Animal类的构造。

package com.lazy.snail.day11;

/**
 * @ClassName Snail
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/5/26 14:04
 * @Version 1.0
 */
public class Snail extends Animal{
    public Snail() {
        super("蜗牛科");
        System.out.println("Snail的无参构造");
    }

    public static void main(String[] args) {
        Snail snail = new Snail();
    }
}

五、构造方法的使用建议

  1. 尽量保留类的无参构造方法
  2. 使用重载提供多种初始化路径
  3. 通过this(...)集中初始化逻辑,减少重复代码
  4. 构造方法中仅做初始化工作,不要写过多的逻辑

构造方法不能被继承,子类必须自定义自己的构造方法 构造方法没有返回值,如果写了返回值类型(比如void),会被当成普通方法 构造方法不能写return 123;但是能写return;提前结束方法。(一般不这么写) 构造方法可以私有化,单例模式使用private构造方法禁止外部实例化。

结语

构造方法是Java对象诞生的出生证明,它定义了对象初始化的核心逻辑。

从new关键字触发的第一行代码,到继承关系中父类构造的隐式调用,构造方法确保了每个对象以合法、完整的姿态进入程序世界。

通过默认构造方法的隐形规则、重载带来的灵活初始化,以及this()和super()的巧妙协作,我们得以在代码中实现高效、可维护的对象构建流程。

记住:保留无参构造、避免冗余逻辑、遵循this和super的调用规范。

下一篇预告

Day12 | Java继承详解

如果你觉得这系列文章对你有帮助,欢迎关注专栏,我们一起坚持下去!

更多文章请关注我的公众号《懒惰蜗牛工坊》