2037 字
约 6 分钟
6
第23章 Java构造函数
2026-09-24
无标签
第23章 Java构造函数
面包屑导航 章节头部 学习目标
学习目标
- 理解构造函数的概念和作用
- 掌握构造函数的定义和调用方式
- 学会构造函数重载的实现方法
- 理解构造函数链式调用(this())的使用
- 掌握构造函数中的参数验证技巧
- 了解构造函数的最佳实践和设计原则
构造函数基础
构造函数基础概念
构造函数是Java中用于初始化对象的特殊方法。当创建类的实例时,构造函数会被自动调用,用于设置对象的初始状态。构造函数具有与类名相同的名称,且没有返回类型。
默认构造函数
public class Student {
private String name;
// 默认构造函数
public Student() {
this.name = "Unknown";
}
}
- 无参数的构造函数
- 提供对象的默认初始化
- 如果没有定义构造函数,Java会自动提供
- 通常用于设置默认值
参数化构造函数
public class Student {
private String name;
private int age;
// 参数化构造函数
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
- 接受参数进行初始化
- 允许创建时指定对象状态
- 提供更灵活的对象创建方式
- 可以进行参数验证
构造函数重载
public class Student {
private String name;
private int age;
public Student() {
this("Unknown", 0);
}
public Student(String name) {
this(name, 0);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
- 同一个类中定义多个构造函数
- 参数列表必须不同
- 提供多种对象创建方式
- 使用this()调用其他构造函数
构造函数链式调用
构造函数链式调用
构造函数链式调用是指在一个构造函数中调用同一个类的另一个构造函数。这种技术可以避免代码重复,提高代码的可维护性。
this()调用规则位置要求:this()调用必须是构造函数的第一条语句参数匹配:根据参数列表匹配对应的构造函数避免循环:不能形成构造函数之间的循环调用代码复用:将通用的初始化逻辑集中在一个构造函数中
public class Rectangle {
private double width;
private double height;
private String color;
// 最完整的构造函数
public Rectangle(double width, double height, String color) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Width and height must be positive");
}
this.width = width;
this.height = height;
this.color = color != null ? color : "white";
}
// 调用完整构造函数,使用默认颜色
public Rectangle(double width, double height) {
this(width, height, "white");
}
// 创建正方形,调用两参数构造函数
public Rectangle(double side) {
this(side, side);
}
// 默认构造函数,创建单位正方形
public Rectangle() {
this(1.0);
}
}
参数验证
构造函数参数验证
在构造函数中进行参数验证是确保对象状态有效性的重要手段。通过验证输入参数,可以防止创建无效的对象实例。
参数验证的重要性防止创建无效状态的对象提供清晰的错误信息遵循"快速失败"原则提高代码的健壮性
public class BankAccount {
private String accountNumber;
private String ownerName;
private double balance;
public BankAccount(String accountNumber, String ownerName, double initialBalance) {
// 验证账号
if (accountNumber == null || accountNumber.trim().isEmpty()) {
throw new IllegalArgumentException("Account number cannot be null or empty");
}
if (!accountNumber.matches("\\d{10}")) {
throw new IllegalArgumentException("Account number must be 10 digits");
}
// 验证姓名
if (ownerName == null || ownerName.trim().isEmpty()) {
throw new IllegalArgumentException("Owner name cannot be null or empty");
}
if (ownerName.length() > 50) {
throw new IllegalArgumentException("Owner name cannot exceed 50 characters");
}
// 验证余额
if (initialBalance < 0) {
throw new IllegalArgumentException("Initial balance cannot be negative");
}
// 设置属性
this.accountNumber = accountNumber;
this.ownerName = ownerName.trim();
this.balance = initialBalance;
}
}
完整代码示例
完整代码示例
以下是一个综合运用构造函数各种特性的完整示例,展示了构造函数的定义、重载、链式调用和参数验证。
public class Person {
private String firstName;
private String lastName;
private int age;
private String email;
// 完整参数构造函数
public Person(String firstName, String lastName, int age, String email) {
validateName(firstName, "First name");
validateName(lastName, "Last name");
validateAge(age);
validateEmail(email);
this.firstName = firstName.trim();
this.lastName = lastName.trim();
this.age = age;
this.email = email.toLowerCase().trim();
}
// 三参数构造函数(无邮箱)
public Person(String firstName, String lastName, int age) {
this(firstName, lastName, age, null);
}
// 两参数构造函数(默认年龄)
public Person(String firstName, String lastName) {
this(firstName, lastName, 0, null);
}
// 私有验证方法
private void validateName(String name, String fieldName) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException(fieldName + " cannot be null or empty");
}
if (name.length() > 30) {
throw new IllegalArgumentException(fieldName + " cannot exceed 30 characters");
}
}
private void validateAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150");
}
}
private void validateEmail(String email) {
if (email != null && !email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) {
throw new IllegalArgumentException("Invalid email format");
}
}
// Getter方法
public String getFullName() {
return firstName + " " + lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public int getAge() { return age; }
public String getEmail() { return email; }
@Override
public String toString() {
return String.format("Person{name='%s', age=%d, email='%s'}",
getFullName(), age, email != null ? email : "N/A");
}
}
💻 查看完整代码 - 在线IDE体验 构造函数最佳实践
构造函数最佳实践
构造函数设计原则
好的实践
// 参数验证
public Student(String name, int age) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be empty");
}
if (age < 0 || age > 120) {
throw new IllegalArgumentException("Invalid age");
}
this.name = name.trim();
this.age = age;
}
// 使用构造函数链式调用
public Student(String name) {
this(name, 18); // 默认年龄
}
// 防御性复制
public Student(List courses) {
this.courses = new ArrayList<>(courses);
}
- 进行参数验证
- 使用构造函数链式调用
- 防御性复制可变对象
- 提供清晰的错误信息
- 保持构造函数简洁
避免的做法
// 不进行参数验证
public Student(String name, int age) {
this.name = name; // 可能为null
this.age = age; // 可能为负数
}
// 在构造函数中调用可重写方法
public Student(String name) {
this.name = name;
initialize(); // 危险!
}
// 构造函数过于复杂
public Student(String name, int age) {
// 大量复杂逻辑...
// 数据库操作...
// 网络请求...
}
- 不验证参数有效性
- 在构造函数中调用可重写方法
- 构造函数逻辑过于复杂
- 直接赋值可变对象引用
- 忽略异常处理
构造函数设计模式
构造函数设计模式
Builder模式与构造函数当构造函数参数过多时,可以考虑使用Builder模式来替代多个重载的构造函数,提供更清晰和灵活的对象创建方式。
public class Computer {
private String cpu;
private String memory;
private String storage;
private String graphics;
// 私有构造函数
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
this.storage = builder.storage;
this.graphics = builder.graphics;
}
public static class Builder {
private String cpu;
private String memory;
private String storage;
private String graphics;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder memory(String memory) {
this.memory = memory;
return this;
}
public Builder storage(String storage) {
this.storage = storage;
return this;
}
public Builder graphics(String graphics) {
this.graphics = graphics;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用示例
Computer computer = new Computer.Builder()
.cpu("Intel i7")
.memory("16GB")
.storage("512GB SSD")
.graphics("RTX 3080")
.build();
本章小结
本章小结
- 构造函数是用于初始化对象的特殊方法,与类名相同且无返回类型
- Java支持构造函数重载,可以提供多种对象创建方式
- 使用this()可以实现构造函数链式调用,避免代码重复
- 构造函数中应该进行参数验证,确保对象状态的有效性
- 遵循构造函数设计最佳实践,保持代码简洁和健壮
- 对于复杂对象,可以考虑使用Builder模式替代多个构造函数
- 构造函数是面向对象编程中对象初始化的重要机制
导航链接 上一章:Java方法 章节测试 下一章:Java继承 JavaScript
评论
0 条
还没有评论,先写一条吧。