Skip to content

10.4 构造方法

构造方法的概念

构造方法是一种特殊的方法,用于创建对象时初始化对象的属性。构造方法的名称与类名相同,没有返回类型。

构造方法的语法

语法:

java
[修饰符] 类名([参数列表]) {
    // 构造方法体
}

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 无参构造方法
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }
    
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

构造方法的特点

  1. 构造方法的名称与类名相同:构造方法的名称必须与类名完全一致,包括大小写
  2. 构造方法没有返回类型:构造方法不需要指定返回类型,甚至不需要使用 void
  3. 构造方法在创建对象时自动调用:当使用 new 关键字创建对象时,会自动调用相应的构造方法
  4. 构造方法可以重载:一个类可以有多个构造方法,只要它们的参数列表不同
  5. 如果没有定义构造方法,Java 会提供默认构造方法:默认构造方法没有参数,也没有方法体

构造方法的类型

1. 无参构造方法

无参构造方法是没有参数的构造方法,用于创建对象时初始化默认值。

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 无参构造方法
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }
}

2. 有参构造方法

有参构造方法是带有参数的构造方法,用于创建对象时初始化指定的值。

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3. 带默认参数的构造方法

在 Java 中,虽然没有直接支持默认参数的语法,但可以通过方法重载来实现类似的功能。

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 无参构造方法
    public Person() {
        this("Unknown", 0); // 调用有参构造方法
    }
    
    // 有参构造方法
    public Person(String name) {
        this(name, 0); // 调用有参构造方法
    }
    
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

构造方法的调用

1. 创建对象时调用

当使用 new 关键字创建对象时,会自动调用相应的构造方法。

示例:

java
// 调用无参构造方法
Person person1 = new Person();

// 调用有参构造方法
Person person2 = new Person("John", 25);

2. 在构造方法中调用其他构造方法

在构造方法中,可以使用 this() 来调用其他构造方法,这种方式称为构造方法的重载。

示例:

java
public class Person {
    private String name;
    private int age;
    private String address;
    
    // 无参构造方法
    public Person() {
        this("Unknown", 0, "Unknown"); // 调用有参构造方法
    }
    
    // 有一个参数的构造方法
    public Person(String name) {
        this(name, 0, "Unknown"); // 调用有参构造方法
    }
    
    // 有两个参数的构造方法
    public Person(String name, int age) {
        this(name, age, "Unknown"); // 调用有参构造方法
    }
    
    // 有三个参数的构造方法
    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

示例:构造方法的使用

示例 1:基本使用

java
public class Student {
    private String name;
    private int studentId;
    private double grade;
    
    // 无参构造方法
    public Student() {
        this.name = "Unknown";
        this.studentId = 0;
        this.grade = 0.0;
    }
    
    // 有参构造方法
    public Student(String name, int studentId, double grade) {
        this.name = name;
        this.studentId = studentId;
        this.grade = grade;
    }
    
    // getter 方法
    public String getName() {
        return name;
    }
    
    public int getStudentId() {
        return studentId;
    }
    
    public double getGrade() {
        return grade;
    }
}

public class StudentExample {
    public static void main(String[] args) {
        // 调用无参构造方法
        Student student1 = new Student();
        System.out.println("Student 1:");
        System.out.println("Name: " + student1.getName());
        System.out.println("Student ID: " + student1.getStudentId());
        System.out.println("Grade: " + student1.getGrade());
        
        // 调用有参构造方法
        Student student2 = new Student("John", 1001, 85.5);
        System.out.println("\nStudent 2:");
        System.out.println("Name: " + student2.getName());
        System.out.println("Student ID: " + student2.getStudentId());
        System.out.println("Grade: " + student2.getGrade());
    }
}

示例 2:构造方法的重载

java
public class Car {
    private String brand;
    private String model;
    private int year;
    private String color;
    
    // 无参构造方法
    public Car() {
        this("Unknown", "Unknown", 0, "Unknown");
    }
    
    // 有一个参数的构造方法
    public Car(String brand) {
        this(brand, "Unknown", 0, "Unknown");
    }
    
    // 有两个参数的构造方法
    public Car(String brand, String model) {
        this(brand, model, 0, "Unknown");
    }
    
    // 有三个参数的构造方法
    public Car(String brand, String model, int year) {
        this(brand, model, year, "Unknown");
    }
    
    // 有四个参数的构造方法
    public Car(String brand, String model, int year, String color) {
        this.brand = brand;
        this.model = model;
        this.year = year;
        this.color = color;
    }
    
    // getter 方法
    public String getBrand() {
        return brand;
    }
    
    public String getModel() {
        return model;
    }
    
    public int getYear() {
        return year;
    }
    
    public String getColor() {
        return color;
    }
}

public class CarExample {
    public static void main(String[] args) {
        // 调用无参构造方法
        Car car1 = new Car();
        System.out.println("Car 1: " + car1.getBrand() + " " + car1.getModel() + " " + car1.getYear() + " " + car1.getColor());
        
        // 调用有一个参数的构造方法
        Car car2 = new Car("Toyota");
        System.out.println("Car 2: " + car2.getBrand() + " " + car2.getModel() + " " + car2.getYear() + " " + car2.getColor());
        
        // 调用有两个参数的构造方法
        Car car3 = new Car("Honda", "Civic");
        System.out.println("Car 3: " + car3.getBrand() + " " + car3.getModel() + " " + car3.getYear() + " " + car3.getColor());
        
        // 调用有三个参数的构造方法
        Car car4 = new Car("Ford", "Mustang", 2022);
        System.out.println("Car 4: " + car4.getBrand() + " " + car4.getModel() + " " + car4.getYear() + " " + car4.getColor());
        
        // 调用有四个参数的构造方法
        Car car5 = new Car("Chevrolet", "Corvette", 2023, "Red");
        System.out.println("Car 5: " + car5.getBrand() + " " + car5.getModel() + " " + car5.getYear() + " " + car5.getColor());
    }
}

示例 3:构造方法中调用其他构造方法

java
public class Person {
    private String name;
    private int age;
    private String address;
    
    // 无参构造方法
    public Person() {
        this("Unknown", 0, "Unknown");
        System.out.println("调用无参构造方法");
    }
    
    // 有一个参数的构造方法
    public Person(String name) {
        this(name, 0, "Unknown");
        System.out.println("调用有一个参数的构造方法");
    }
    
    // 有三个参数的构造方法
    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
        System.out.println("调用有三个参数的构造方法");
    }
    
    // getter 方法
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public String getAddress() {
        return address;
    }
}

public class PersonExample {
    public static void main(String[] args) {
        System.out.println("创建 person1:");
        Person person1 = new Person();
        System.out.println("Name: " + person1.getName() + ", Age: " + person1.getAge() + ", Address: " + person1.getAddress());
        
        System.out.println("\n创建 person2:");
        Person person2 = new Person("John");
        System.out.println("Name: " + person2.getName() + ", Age: " + person2.getAge() + ", Address: " + person2.getAddress());
        
        System.out.println("\n创建 person3:");
        Person person3 = new Person("Jane", 30, "New York");
        System.out.println("Name: " + person3.getName() + ", Age: " + person3.getAge() + ", Address: " + person3.getAddress());
    }
}

默认构造方法

如果一个类没有定义构造方法,Java 会自动提供一个无参构造方法,称为默认构造方法。默认构造方法没有参数,也没有方法体。

示例:

java
public class Person {
    private String name;
    private int age;
    // 没有定义构造方法,Java 会提供默认构造方法
}

// 使用默认构造方法创建对象
Person person = new Person();

注意: 如果一个类定义了构造方法,Java 就不会再提供默认构造方法。因此,如果需要使用无参构造方法,应该显式定义它。

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 定义了有参构造方法,Java 不会再提供默认构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 如果需要使用无参构造方法,应该显式定义它
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }
}

构造方法的访问修饰符

构造方法可以使用访问修饰符,控制构造方法的访问权限:

  • public:公共构造方法,任何类都可以访问
  • protected:受保护构造方法,同一个包或子类可以访问
  • default:默认构造方法,同一个包可以访问
  • private:私有构造方法,只有本类可以访问

示例:

java
public class Person {
    private String name;
    private int age;
    
    // 公共构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 私有构造方法
    private Person() {
        this.name = "Unknown";
        this.age = 0;
    }
}

私有构造方法的应用

私有构造方法通常用于以下场景:

  1. 单例模式:确保一个类只有一个实例
  2. 工具类:只提供静态方法,不允许创建对象

示例: 单例模式

java
public class Singleton {
    // 私有静态变量,存储唯一实例
    private static Singleton instance;
    
    // 私有构造方法,防止外部创建实例
    private Singleton() {
    }
    
    // 公共静态方法,获取唯一实例
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

示例: 工具类

java
public class MathUtils {
    // 私有构造方法,防止外部创建实例
    private MathUtils() {
    }
    
    // 公共静态方法
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static int subtract(int a, int b) {
        return a - b;
    }
}

常见问题

1. 构造方法名称错误

症状:编译错误:Method does not override method from its superclass

解决方案:确保构造方法的名称与类名完全一致,包括大小写

示例:

java
public class Person {
    // 错误:构造方法名称与类名不一致
    public person() {
    }
}

2. 构造方法返回类型错误

症状:编译错误:Constructor cannot have a return type

解决方案:构造方法不能有返回类型,包括 void

示例:

java
public class Person {
    // 错误:构造方法不能有返回类型
    public void Person() {
    }
}

3. 缺少构造方法

症状:编译错误:The constructor Person() is undefined

解决方案:如果需要使用无参构造方法,应该显式定义它

示例:

java
public class Person {
    // 定义了有参构造方法
    public Person(String name, int age) {
    }
    
    // 缺少无参构造方法
}

// 会导致编译错误
Person person = new Person();

4. 构造方法调用错误

症状:编译错误:Constructor call must be the first statement in a constructor

解决方案:在构造方法中调用其他构造方法时,this() 必须是第一条语句

示例:

java
public class Person {
    public Person() {
        System.out.println("Hello");
        // 错误:this() 必须是第一条语句
        this("Unknown", 0);
    }
    
    public Person(String name, int age) {
    }
}

最佳实践

  1. 提供无参构造方法:即使定义了有参构造方法,也应该提供无参构造方法,以便于创建对象
  2. 使用构造方法初始化属性:在构造方法中初始化对象的属性,确保对象状态正确
  3. 使用构造方法重载:通过构造方法重载,提供多种创建对象的方式
  4. 在构造方法中调用其他构造方法:使用 this() 调用其他构造方法,减少代码重复
  5. 合理使用访问修饰符:根据需要选择合适的访问修饰符,控制构造方法的访问权限

总结

构造方法是一种特殊的方法,用于创建对象时初始化对象的属性。构造方法的名称与类名相同,没有返回类型。

构造方法的特点:

  • 构造方法的名称与类名相同
  • 构造方法没有返回类型
  • 构造方法在创建对象时自动调用
  • 构造方法可以重载
  • 如果没有定义构造方法,Java 会提供默认构造方法

构造方法的类型:

  • 无参构造方法
  • 有参构造方法
  • 带默认参数的构造方法

通过合理使用构造方法,可以确保对象在创建时状态正确,提高代码的可读性和可维护性。

© 2026 编程马·菜鸟教程 版权所有