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();
}
}
五、构造方法的使用建议
- 尽量保留类的无参构造方法
- 使用重载提供多种初始化路径
- 通过this(...)集中初始化逻辑,减少重复代码
- 构造方法中仅做初始化工作,不要写过多的逻辑
构造方法不能被继承,子类必须自定义自己的构造方法 构造方法没有返回值,如果写了返回值类型(比如void),会被当成普通方法 构造方法不能写return 123;但是能写return;提前结束方法。(一般不这么写) 构造方法可以私有化,单例模式使用private构造方法禁止外部实例化。
结语
构造方法是Java对象诞生的出生证明,它定义了对象初始化的核心逻辑。
从new关键字触发的第一行代码,到继承关系中父类构造的隐式调用,构造方法确保了每个对象以合法、完整的姿态进入程序世界。
通过默认构造方法的隐形规则、重载带来的灵活初始化,以及this()和super()的巧妙协作,我们得以在代码中实现高效、可维护的对象构建流程。
记住:保留无参构造、避免冗余逻辑、遵循this和super的调用规范。
下一篇预告
Day12 | Java继承详解
如果你觉得这系列文章对你有帮助,欢迎关注专栏,我们一起坚持下去!
更多文章请关注我的公众号《懒惰蜗牛工坊》