setter/getter的基本概念与封装性

在Java面向对象编程中,setter和getter方法是实现封装性的核心手段,封装要求将类的内部数据隐藏,通过公开的方法控制外部对数据的访问和修改,直接将属性声明为public会导致数据被随意篡改,破坏类的稳定性,而通过private修饰属性,再提供public的setter(设置值)和getter(获取值)方法,既能保护数据安全,又能灵活控制访问逻辑,一个User类的age属性,若直接暴露为public,外部可能将其设置为负数;而通过setter方法,可在设置前添加校验逻辑,确保age的合法性,这种“属性私有化+方法公开化”的模式,是JavaBean规范的基础,也是代码可维护性的重要保障。
setter/getter的语法规范
定义setter和getter方法需遵循Java命名规范,以确保代码可读性和一致性,对于任意属性,其setter和getter方法的命名规则如下:
- setter方法:方法名以“set”开头,后跟属性名的首字母大写形式,参数类型与属性类型一致,返回值为void,属性为String name,则setter方法为setName(String name)。
- getter方法:方法名以“get”开头,后跟属性名的首字母大写形式,无参数,返回值类型与属性类型一致,属性为int age,则getter方法为getAge()。
- 布尔类型特例:若属性为boolean类型,getter方法可采用“is”开头,如boolean isVip(),也可使用getIsVip(),但“is”前缀更符合语义习惯。
定义一个Student类:
public class Student {
private String studentId; // 学号
private String name; // 姓名
private boolean isActive; // 是否在读状态
// setter方法
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public void setName(String name) {
this.name = name;
}
public void setActive(boolean active) {
isActive = active;
}
// getter方法
public String getStudentId() {
return studentId;
}
public String getName() {
return name;
}
public boolean isActive() { // 布尔类型使用is前缀
return isActive;
}
}
实战案例:从属性封装到数据校验
setter/getter的实际价值不仅在于封装,更在于通过方法内部逻辑实现数据控制,一个商品类Product,其价格(price)和库存(stock)属性需要严格校验,避免出现负值或无效数据。

public class Product {
private String productId;
private String productName;
private double price; // 价格
private int stock; // 库存
// setter方法:添加数据校验逻辑
public void setPrice(double price) {
if (price < 0) {
throw new IllegalArgumentException("价格不能为负数");
}
this.price = price;
}
public void setStock(int stock) {
if (stock < 0) {
throw new IllegalArgumentException("库存不能为负数");
}
this.stock = stock;
}
// getter方法:可返回格式化或计算后的数据
public String getFormattedPrice() {
return String.format("%.2f元", price); // 格式化价格显示
}
public int getAvailableStock() {
return stock > 0 ? stock : 0; // 库存不足时返回0
}
// 其他getter/setter...
}
在上述代码中,setPrice()和setStock()方法通过校验逻辑确保数据合法性,而getFormattedPrice()和getAvailableStock()则对返回值进行了额外处理,体现了方法的灵活性。
进阶技巧:链式调用与只读属性
-
链式调用:通过让setter方法返回当前对象(this),可实现连续调用多个setter方法,提升代码简洁性。
User user = new User() .setName("张三") .setAge(25) .setEmail("zhangsan@example.com"); -
只读属性:若某个属性只需被获取而无需修改,可仅提供getter方法,并将属性声明为private final,订单类中的订单号(orderId)通常生成后不再变更:
public class Order { private final String orderId; // 只读属性 public Order(String orderId) { this.orderId = orderId; } public String getOrderId() { return orderId; } // 不提供setter方法,确保orderId不可修改 }
工具简化:Lombok的使用
手动编写大量getter/setter方法会降低开发效率,Lombok库通过注解自动生成这些方法,只需在类上添加@Data(包含所有getter/setter、toString、equals等方法)或分别使用@Getter/@Setter注解:

import lombok.Data;
@Data
public class User {
private String name;
private int age;
private String email;
}
编译后,Lombok会自动生成标准的getter/setter方法,减少模板代码,但需注意项目环境已配置Lombok插件。
常见误区与最佳实践
- 避免方法逻辑过重:setter/getter应保持简洁,避免在方法中包含耗时操作(如IO、复杂计算),以免破坏方法的“设置/获取”单一职责。
- 慎用public属性:即使属性无需校验,也应通过private+getter/setter封装,以应对未来需求变更(如添加日志、权限控制)。
- 命名一致性:严格遵循驼峰命名法,避免将getter命名为getAttribute(除非属性本身是boolean且符合is前缀规范)。
通过合理使用setter/getter方法,既能实现数据的封装与安全控制,又能提升代码的可读性和可维护性,是Java开发者必须掌握的基础技能。














