Java中如何从一个构造函数调用另一个构造函数

Java中如何从一个构造函数调用另一个构造函数

技术背景

在Java编程中,一个类可能会有多个构造函数,以满足不同的对象初始化需求。为了避免代码重复,提高代码的可维护性,我们常常需要从一个构造函数调用另一个构造函数。这种调用方式有助于实现构造函数之间的复用,减少冗余代码。

实现步骤

调用同一个类的构造函数

在同一个类中,可以使用this()this(args)来调用另一个构造函数,但这个调用必须是构造函数体中的第一条语句。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
public class Foo {
private int x;

public Foo() {
this(1);
}

public Foo(int x) {
this.x = x;
}
}

在上述代码中,无参构造函数Foo()调用了带参构造函数Foo(int x)

调用父类的构造函数

使用super()super(args)来调用父类的构造函数,同样,这个调用必须是构造函数体中的第一条语句。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class SuperClass {
public SuperClass() {
System.out.println("Inside super class constructor");
}
}

public class SubClass extends SuperClass {
public SubClass() {
// 即使不添加,Java也会自动添加对父类构造函数的调用,即 super();
System.out.println("Inside sub class constructor");
}
}

核心代码

同一个类中构造函数的链式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Rectangle {
private int x, y;
private int width, height;

public Rectangle() {
this(1, 1);
}

public Rectangle(int width, int height) {
this(0, 0, width, height);
}

public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}

调用父类构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Animal {
String i;

public Animal() {
i = "10";
System.out.println("Animal Constructor :" + i);
}

public Animal(String h) {
i = "20";
System.out.println("Animal Constructor Habit :" + i);
}
}

class Cat extends Animal {
public Cat() {
System.out.println("Cat Constructor");
}

public Cat(String i) {
super(i); // 调用父类的带参构造函数
System.out.println("Cat Constructor with habit");
}
}

最佳实践

从简单构造函数调用复杂构造函数

尽量从简单的构造函数调用更复杂的构造函数,这样可以确保初始化逻辑的一致性。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClass {
int field;

MyClass(int value) {
if (value < 0)
field = 0;
else
field = value;
}

MyClass() {
this(0);
}
}

使用静态方法构造参数

this()必须在第一行的限制带来不便时,可以通过静态方法来构造其他构造函数的参数。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, getDefaultArg3(argument1, argument2));
}

public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}

private static double getDefaultArg3(double argument1, double argument2) {
double argument3 = 0;
// 在这里计算 argument3
return argument3;
}
}

常见问题

调用必须是第一行

在构造函数中使用this()super()调用其他构造函数时,这个调用必须是构造函数体中的第一条语句,否则会导致编译错误。

示例:

1
2
3
4
5
// 错误示例
public Product(int id, String name, double price) {
System.out.println("Calling constructor with price");
this(id, name, price, "DEFAULT");
}

避免在显式构造函数调用中引用实例成员

在显式构造函数调用语句中,不能引用任何实例变量、实例方法、内部类、thissuper。这是Java语言规范(JLS §8.8.7.1)的规定。

构造函数过多时考虑设计模式

如果一个类需要多个构造函数,可能会导致代码复杂,此时可以考虑使用其他设计模式,如Builder模式。

文章参考:
Constructor Chaining in Java
Design Patterns 2: The Builder Pattern and the Telescoping Constructor Anti-Pattern


Java中如何从一个构造函数调用另一个构造函数
https://119291.xyz/posts/2025-05-13.java-constructor-calling-guide/
作者
ww
发布于
2025年5月13日
许可协议