1. 构造器
1.1 构造器的核心意义
1.1.1 对象初始化
- 构造器在创建对象 (new) 时自动调用, 用于初始化对象的状态 (如设置字段初始值, 分配资源等)
- 无构造器时: 字段为默认值(
0
/null
/false
) 有构造器:确保对象创建后即处于有效状态
- 无构造器时: 字段为默认值(
- 构造器在创建对象 (new) 时自动调用, 用于初始化对象的状态 (如设置字段初始值, 分配资源等)
1.1.2 强制初始化
- 通过有参构造器强制要求调用方必须提供必要参数, 避免对象状态不完整 (如必须传入用户ID)。
1.1.3 代码复用(重载机制)
- 通过
this()
调用其他构造器,减少重复代码(构造器重载时)。
- 通过
1.1.4 封装控制(支持不可变的对象设计)
- 私有构造器可限制对象创建 (单例模式, 工具类禁止实例化)
1.2 构造器的基础语法
- 代码示例
public class Car {private String brand;private int price;//无参构造public Car() {this.brand = "UNknow";this.price = 0;}//有参构造1public Car(String brand, int price) {this.brand = brand;this.price = price;}//有参构造2public Car(String brand) {this.brand = brand;} }
1.3 构造器的关键特性
- a. 命名: 必须与类名完全相同
- b. 无返回值: 不可声名返回类型(连void都不行)
- c. 自动调用: new 关键字自动调用
- d. 默认构造器: 未显式定义构造器时编译器会自动生成一个无参构造器; 定义后则不会再生成
- e. 支持重载: 可定义多个参数不同的构造器
1.4 进阶用法
1.4.1 构造器链
- 使用 (this) 关键字调用本类其他构造器(必须放在第一行)
- 代码示例:
//有参构造1public Car(String brand, int price) {this.brand = brand;this.price = price;}//有参构造2public Car(String brand) {this(brand, 100000);//调用上面的双参构造器}
1.4.2 父类构造器调用
- 子类构造器必须调用父类构造器(显式或隐式) 使用
super(...) (
必须第一行) 1.4.2.1 可以不写 super() 的情况:
- 父类存在无参构造器时 (显式定义或编译器自动生成), 子类构造器会隐式调用super() , 此时无需显式写出, 编译器会自动在第一行插入super()
class Parent {// 编译器自动生成默认无参构造器:Parent() {} }class Child extends Parent {// 编译器自动添加:super();public Child() {System.out.println("Child构造器");} }
1.4.2.2 必须写 super() 的情况
- a. 父类没有无参构造器
- 若父类定义了有参构造器且未定义无参构造器时, 编译器不会生成默认无参构造器
子类必须显式调用父类的某个带参构造器,否则编译报错。
- b. 父类构造器有重载时需要明确指定
- 若父类有多个构造器, 子类需要通过 super() 来选择调用哪一个
class ElectricCar extends Car{private int battery;public ElectricCar(String brand , int price , int battery){super(brand ,price);//先初始化父类(调用父类构造器)this.battery=battery;} }class GasCar extends Car{private int gas;public GasCar (String brand , int price , int gas){super(brand);this.gas=gas;} }
- a. 父类没有无参构造器
1.4.2.3 特殊规则
- 1.
this()
和super()
不能共存- a. 若子类构造器第一行用
this(...)
调用本类其他构造器,则不能再写super()
。 - b. 被调用的本类构造器最终仍需调用
super(...)
class GasCar extends Car {private int gas;public GasCar() {this(100);//// 调用GasCar类的其他构造器}public GasCar(int gas) {super("车车");} }
- a. 若子类构造器第一行用
- 2. 继承链的顶端是
Object
- 所有类的终极父类是
Object
,其有无参构造器Object()
,因此最顶层的super()
调用总是安全的
- 所有类的终极父类是
- 1.
- 子类构造器必须调用父类构造器(显式或隐式) 使用
1.4.3 私有构造器应用场景
1.4.3.1 单例模式: 全局唯一实例
public class Parents {private static final Parents Child = new Parents();//创建全局唯一实例private Parents(){// 私有构造器}public static Parents getInstance(){return Child;//返回唯一的实例} }
1.4.3.2 工具类: 禁止实例化 (Math类等)
public class StringUtils {private StringUtils() {} // 防止 new StringUtils()public static boolean isEmpty(String s) { ... } }
1.4.4 初始化顺序
- 对象创建时的执行顺序:
- 父类静态块 -> 子类静态块 -> 父类字段初始化 -> 父类构造器 -> 子类字段初始化 -> 子类构造器
1.5 常见问题
- Q: 为什么构造器不能有返回值?
- A: 构造器隐含返回新对象,声明返回值会导致编译器将其视为普通方法。
- Q: 构造器能被
static
/final
修饰吗?- A: 不能! 构造器属于对象初始化机制,与类级别(
static
)和继承(final
)无关。
- A: 不能! 构造器属于对象初始化机制,与类级别(
- Q: 子类如何调用父类带参构造器?
- A: 通过super() 显式调用, 否则编译器会自动调用父类的无参构造器
- Q: 为什么构造器不能有返回值?
2. 静态工厂方法
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s
- s