目录
封装是面向对象编程的三大特性之一,而getter和setter方法是实现封装的基本手段。本文将全面探讨getter/setter方法的存在意义、使用场景以及相关争议,帮助开发者做出更合理的设计决策。
一、封装的基本概念与价值
1.1 什么是封装
封装(Encapsulation)是指将对象的状态信息(属性)和行为(方法)捆绑在一起,并对外部隐藏对象的内部实现细节。在Java中,封装主要通过以下方式实现:
- 使用private修饰成员变量
- 提供public的getter/setter方法
- 在方法中加入业务逻辑控制
1.2 封装带来的好处
优势 | 说明 | 示例 |
---|---|---|
数据保护 | 防止对象属性被不合理修改 | 年龄不能设为负数 |
灵活性 | 可随时修改内部实现而不影响调用方 | 字段类型从String改为枚举 |
可维护性 | 集中控制对属性的访问逻辑 | 所有赋值操作都经过校验 |
隐藏复杂性 | 对外暴露简单接口,隐藏复杂实现 | 计算属性替代直接存储 |
二、getter/setter方法详解
2.1 标准getter/setter模式
public class Person {
private String name;
private int age;
// getter方法
public String getName() {
return name;
}
// setter方法
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("姓名不能为空");
}
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄不合法");
}
this.age = age;
}
}
2.2 getter/setter的多种变体
2.2.1 只读属性(只有getter)
public class Circle {
private double radius;
public double getRadius() {
return radius;
}
// 没有setter,通过构造方法初始化
public Circle(double radius) {
setRadius(radius);
}
private void setRadius(double radius) {
if (radius <= 0) {
throw new IllegalArgumentException("半径必须为正数");
}
this.radius = radius;
}
}
2.2.2 延迟初始化
public class HeavyObject {
private ExpensiveResource resource;
public ExpensiveResource getResource() {
if (resource == null) {
resource = loadResource(); // 延迟加载
}
return resource;
}
}
2.2.3 计算属性
public class Rectangle {