Java构造方法

构造方法的基本概念与作用

在Java面向对象编程中,构造方法(Constructor)是创建对象时必须调用的特殊方法,它负责对象的初始化工作。与普通方法相比,构造方法具有以下特点:

  • 构造方法的名称必须与类名完全相同
  • 构造方法没有返回值,也不能使用void声明
  • 构造方法可以重载(定义多个参数不同的构造方法)
  • 构造方法必须通过new操作符调用

为什么需要构造方法?

在没有构造方法的情况下,创建对象后需要单独调用setter方法初始化字段:

Person person = new Person();
person.setName("张三");
person.setAge(25);

这种方式存在两个问题:一是步骤繁琐,二是可能遗漏某些初始化步骤导致对象状态不正确。构造方法可以解决这些问题,在创建对象的同时完成初始化

// 使用构造方法创建并初始化对象
Person person = new Person("张三", 25);

构造方法的定义与使用

基本语法

public class 类名 {
// 字段定义
private 类型 字段1;
private 类型 字段2; // 构造方法
public 类名(参数1, 参数2, ...) {
// 初始化字段
this.字段1 = 参数1;
this.字段2 = 参数2;
// 其他初始化逻辑
}
}

示例:为Person类定义构造方法

public class Person {
private String name;
private int age; // 构造方法:初始化name和age字段
public Person(String name, int age) {
this.name = name;
this.age = age;
} // getter方法
public String getName() {
return name;
} public int getAge() {
return age;
} public static void main(String[] args) {
// 使用构造方法创建对象
Person person = new Person("张三", 25);
System.out.println("姓名:" + person.getName()); // 输出"张三"
System.out.println("年龄:" + person.getAge()); // 输出25
}
}

在这个例子中,Person类定义了一个接收nameage参数的构造方法,通过new Person("张三", 25)创建对象时,会自动调用该构造方法完成初始化。

注:虽然构造方法本身不写返回值,但 new 操作会返回对象引用。

默认构造方法

如果一个类没有显式定义任何构造方法,Java编译器会自动生成一个默认构造方法。默认构造方法没有参数,也没有任何执行语句:

public class Person {
private String name;
private int age; // 编译器自动生成的默认构造方法
public Person() {
// 空方法体
}
}

此时可以通过new Person()创建对象:

Person person = new Person(); // 调用默认构造方法

注意事项

  • 一旦显式定义了任何构造方法,编译器将不再生成默认构造方法
  • 如果需要同时支持无参数创建对象,必须显式定义无参数构造方法
public class Person {
private String name;
private int age; // 显式定义有参数构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
} // 显式定义无参数构造方法
public Person() {
// 可以在这里设置默认值
this.name = "未知姓名";
this.age = 0;
}
}

构造方法的重载

与普通方法一样,构造方法也支持重载(Overload),即一个类可以定义多个构造方法,只要它们的参数列表(参数数量、类型或顺序)不同。

示例:重载构造方法

public class Person {
private String name;
private int age; // 构造方法1:无参数
public Person() {
this.name = "未知姓名";
this.age = 0;
} // 构造方法2:仅初始化name
public Person(String name) {
this.name = name;
this.age = 0; // 默认年龄为0
} // 构造方法3:初始化name和age
public Person(String name, int age) {
this.name = name;
this.age = age;
} // getter方法省略...
}

创建对象时,编译器会根据传入的参数自动匹配对应的构造方法:

Person p1 = new Person();                  // 调用无参数构造方法
Person p2 = new Person("李四"); // 调用Person(String)构造方法
Person p3 = new Person("王五", 30); // 调用Person(String, int)构造方法

构造方法的相互调用

为了避免代码重复,一个构造方法可以通过this(参数)调用另一个构造方法,这种方式称为构造方法的链式调用

示例:构造方法间的调用

public class Person {
private String name;
private int age; // 完整参数的构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
} // 仅name参数的构造方法,调用完整参数构造方法
public Person(String name) {
this(name, 18); // 调用Person(String, int),默认年龄18
} // 无参数构造方法,调用单参数构造方法
public Person() {
this("未知姓名"); // 调用Person(String)
}
}

这种设计的好处是:

  • 减少代码重复,提高维护性
  • 确保初始化逻辑的一致性
  • 新增初始化步骤时只需修改一个构造方法

注意:this(...)必须是构造方法的第一条语句,否则会编译错误。

对象初始化顺序

当创建对象时,Java会按照特定的顺序进行初始化:

  1. 初始化字段的默认值或显式赋值(字段定义时的初始化)
  2. 执行构造方法中的代码

示例:初始化顺序演示

public class Person {
// 字段显式初始化
private String name = "初始化值";
private int age = 10; public Person(String name, int age) {
this.name = name;
this.age = age;
} public static void main(String[] args) {
Person person = new Person("张三", 25);
System.out.println(person.name); // 输出"张三"(构造方法覆盖了初始值)
System.out.println(person.age); // 输出25(构造方法覆盖了初始值)
}
}

在这个例子中:

  • 字段首先被初始化为name="初始化值"age=10
  • 然后执行构造方法,将name改为"张三",age改为25
  • 最终对象的字段值由构造方法确定

注意事项

  1. 参数验证:在构造方法中可以对参数进行合法性检查,避免创建无效对象
public Person(String name, int age) {
// 验证参数
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("姓名不能为空");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在0-150之间");
}
this.name = name;
this.age = age;
}
  1. 提供必要的构造方法重载:根据使用场景提供不同参数组合的构造方法,但不宜过多

  2. 使用构造方法链:通过this(...)调用减少代码重复

综合示例:构造方法的实际应用

import java.time.LocalDate;

public class Student {
private String id; // 学号(必填)
private String name; // 姓名(必填)
private int grade; // 年级(可选,默认1)
private LocalDate enrollDate; // 入学日期(可选,默认当前日期) // 完整参数构造方法
public Student(String id, String name, int grade, LocalDate enrollDate) {
// 参数验证
if (id == null || id.isBlank()) {
throw new IllegalArgumentException("学号不能为空");
}
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("姓名不能为空");
}
if (grade < 1 || grade > 12) {
throw new IllegalArgumentException("年级必须在1-12之间");
} this.id = id;
this.name = name;
this.grade = grade;
this.enrollDate = enrollDate;
} // 省略入学日期的构造方法
public Student(String id, String name, int grade) {
this(id, name, grade, LocalDate.now()); // 调用完整构造方法,默认当前日期
} // 省略年级和入学日期的构造方法
public Student(String id, String name) {
this(id, name, 1); // 调用上一个构造方法,默认1年级
} // getter方法
public String getId() { return id; }
public String getName() { return name; }
public int getGrade() { return grade; }
public LocalDate getEnrollDate() { return enrollDate; } public static void main(String[] args) {
Student s1 = new Student("S001", "张三", 3);
System.out.println(s1.getName() + "," + s1.getGrade() + "年级"); Student s2 = new Student("S002", "李四");
System.out.println(s2.getName() + "," + s2.getGrade() + "年级");
}
}

总结

  • 掌握构造方法的使用,构造方法用于在创建对象时初始化字段:

    • 名称与类名相同无返回值
    • 未显式定义构造方法时,编译器会生成默认无参数构造方法
    • 构造方法可以重载,通过参数列表区分不同的构造方法
  • 了解即可:
    • 构造方法之间可以通过this(...)相互调用,减少代码重复
    • 对象初始化顺序:先初始化字段,再执行构造方法

Java面向对象基础——2.构造方法的更多相关文章

  1. 085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用

    085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用 本文知识点:构造方法调用 说明:因为时间紧张,本人写博客过程中只是 ...

  2. 084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字

    084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字 本文知识点:构造方法-this关键字 说明:因为时间紧 ...

  3. 083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法

    083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法 本文知识点:构造方法-带参构造方法 说明:因为时间紧张, ...

  4. 082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法

    082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法 本文知识点:构造方法-无参构造方法 说明:因为时间紧张, ...

  5. 【重走Android之路】【Java面向对象基础(三)】面向对象思想

    [重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想   1 面向对象的WWH   1.1 What--什么是面向对象         首先,要理解“对象”.在Thinkin ...

  6. 【重走Android之路】【Java面向对象基础(一)】数据类型与运算符

    [重走Android之路][基础篇(一)][Java面向对象基础]数据类型与运算符   1.数据类型介绍 在Java中,数据类型分为两种:基本数据类型和引用类型. 基本数据类型共8种,见下表: 基本数 ...

  7. 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结

    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...

  8. 【重走Android之路】【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder

    [重走Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder   1.String String是Java中的一个final ...

  9. 081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字

    081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字 本文知识点:new关键字 说明:因为时间紧张,本人写博客过程中只是 ...

  10. 080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则

    080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则 本文知识点:单一职责原则 说明:因为时间紧张,本人写博客过程中只是 ...

随机推荐

  1. Java 代码块与代码加载顺序

    本文首先介绍几个基本的名次,然后介绍了三种代码块的特性和使用方法. 在面试大型公司时,如果遇到大型国企或者大的互联网私企,笔试中经常遇到代码块和代码加载顺序的笔试题.这里做一个总结,也方便各位小伙伴飙 ...

  2. 2023电赛E题代码

    openmv: import sensor, image, time from pyb import LED, UART #import lcd import json, ustruct class ...

  3. FastAPI认证系统:从零到令牌大师的奇幻之旅

    title: FastAPI认证系统:从零到令牌大师的奇幻之旅 date: 2025/06/06 16:13:06 updated: 2025/06/06 16:13:06 author: cmdra ...

  4. GGTalk 开源即时通讯系统源码剖析之:远程磁盘 (低调赠送GGTalk最新源码)

    继上篇<GGTalk 开源即时通讯系统源码剖析之:聊天消息防错漏机制>介绍了 GGTalk 对消息的可靠性,即消息的不丢失和不重复做了一系列优化处理,以保证不会错漏消息.这篇我们来剖析 G ...

  5. 从 TCP 到 WebSocket:一次搞懂网络通信的三层演进

    引言 在现代应用开发中,网络通信是绕不开的核心议题.无论是构建传统的 Web 应用,还是开发需要实时交互的系统(如在线协作工具.金融行情推送.多人游戏),我们总会与 TCP.HTTP.WebSocke ...

  6. C++ set/multiset容器 学习总结

    -------------------------------------set/multiset容器 set/multiset特性 set/multiset的特性是所有元素会根据元素的值自动进行排序 ...

  7. [CSP-S 2022] 星战

    link 我为什么会在赛时想图论分块.... 什么神仙会想到哈希维护啊 首先手玩一下满足条件的图,只需要满足条件二:所有点出度为 1,条件 1 会自然满足,我们必然可以顺着其出边走下去. 对于操作 2 ...

  8. Windows 的桌面图标没有显示正确

    Windows系统会缓存桌面图标,如果缓存文件损坏,可能会导致图标不显示.我们可以通过以下步骤重建图标缓存: 打开"任务管理器",结束"Windows资源管理器" ...

  9. 修改Git全部Commit提交记录的用户名Name和邮箱Email

    当我们换邮箱了,想把已经提交过的 commit 的邮箱和用户名改成新的时候. 先把本地配置成新的 git config user.name '丁少华' git config user.email '新 ...

  10. CF1990C Mad MAD Sum 题解

    CF1990C Mad MAD Sum 好题.考虑操作一次之后序列的性质,不难发现存在单调性.因为定义为出现至少两次的最大值,而从左到右最大值是可以继承的,所以单升不降. 然后,手玩一下发现之后的操作 ...