Getters 和 Setters 在 Java 中:它们真正的作用是什么?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:“为什么不直接把字段设为 public?”



想象一下:你在 Java 中编写一个 Person 类。它包含姓名、年龄和电子邮件。最简单的方式是将字段声明为 public 并直接访问它们:



public class Person {    public String name;    public int age;    public String email;}


“这样也能用啊!”你可能会说。“为什么我需要那些 getters 和 setters?多余的代码,还让代码行数膨胀……”



这个问题是 Stack Overflow 上最热门的问题之一。成千上万的开发者,尤其是新手,都会问这个问题。你从经验丰富的 Java 程序员那里得到的答案会很简短:封装。但这个词背后隐藏着一整套设计哲学,它能拯救项目于混乱之中。



在这篇文章中,我们不仅仅是给出定义。我们将深入探讨 getters 和 setters(也称为 accessors 和 mutators)所解决的实际问题,并通过实际代码向你展示。开始吧!



1. 封装:不仅仅是一个时髦的词



封装 是面向对象编程(OOP)的一个原则,它规定:隐藏对象的内部实现,并提供受控的接口与之交互。Getters 和 setters 正是那个受控的接口。



比较两种方法:



糟糕的方法(public 字段)

Person person = new Person();person.age = -5; // 负年龄?轻而易举!person.email = "not-an-email"; // 垃圾数据无需检查即可通过


好的方法(getters 和 setters)

public class Person {    private String name;    private int age;    private String email;

public int getAge() { return age; }

public void setAge(int age) { if (age < 0 || age > 150) { throw new IllegalArgumentException("年龄必须在 0 到 150 之间"); } this.age = age; }

public String getEmail() { return email; }

public void setEmail(String email) { if (email == null || !email.contains("@")) { throw new IllegalArgumentException("电子邮件格式不正确"); } this.email = email; }

// 其余的 getters/setters...}


现在,如果有人试图将年龄设置为 -5,程序将抛出异常。数据得到了保护。这就是封装的力量。



2. 即时数据验证



Setters 是检查输入数据的理想场所。没有它们,你不得不在每个赋值的地方编写验证代码。这会导致代码重复,并且存在忘记在某些地方进行验证的风险。



银行账户示例:



public class BankAccount {    private double balance;

public double getBalance() { return balance; }

public void deposit(double amount) { if (amount <= 0) { throw new IllegalArgumentException("存款金额必须为正数"); } this.balance += amount; }

public void withdraw(double amount) { if (amount <= 0) { throw new IllegalArgumentException("取款金额必须为正数"); } if (amount > balance) { throw new IllegalStateException("余额不足"); } this.balance -= amount; }}


请注意:这里没有直接为 balance 设置 setter。我们通过 deposit 和 withdraw 方法来管理余额,这些方法已经包含了所有检查逻辑。Getter 则只是返回当前状态。



3. 灵活性:你可以在不破坏代码的情况下更改实现



想象一下,你将年龄存储在 int 字段中,然后决定存储出生日期并动态计算年龄。如果你有

博客

书籍推荐