杰瑞科技汇

Java中set/get方法为何存在?

什么是 setget 方法?

setget 方法,通常被称为 访问器方法存取器方法

Java中set/get方法为何存在?-图1
(图片来源网络,侵删)
  • get 方法 (Getter):用于获取(读取)一个对象的私有成员变量的值。
  • set 方法 (Setter):用于设置(修改)一个对象的私有成员变量的值。

它们遵循一种特定的命名规范,这使得代码非常易于阅读和理解。


为什么需要 setget 方法?(核心思想)

直接问这个问题:为什么我们不直接把成员变量设为 public,然后直接在外部访问和修改它们呢?

为什么不这样做:

// 不推荐的做法
public class Person {
    public String name; // 公开的成员变量
    public int age;     // 公开的成员变量
}

这样做有几个致命的缺点:

Java中set/get方法为何存在?-图2
(图片来源网络,侵删)
  1. 数据无保障:任何人都可以随意修改你的变量,而无需经过任何检查,你可以把年龄设置为负数:person.age = -100,这在逻辑上是错误的。
  2. 代码脆弱:如果业务逻辑发生变化,比如所有年龄计算都需要以“周岁”为准,但你之前已经把变量直接暴露出去了,那么所有直接使用这个变量的地方都需要修改,工作量巨大且容易出错。
  3. 无法添加额外逻辑:你可能希望在设置年龄时,打印一条日志;或者在获取名字时,进行一些格式化处理,如果变量是 public 的,你无法在这些操作发生时插入逻辑。

setget 方法就是为了解决以上问题而生的。

核心优势:

  • 封装:这是面向对象三大特性(封装、继承、多态)之一,通过将成员变量设为 private(私有),我们将其“隐藏”在类内部,只通过 public(公有)的 setget 方法来提供受控的访问。
  • 数据保护:你可以在 set 方法中加入验证逻辑,确保只有合法的值才能被赋给变量。
  • 灵活性:你可以在不改变外部接口(setget 方法的签名)的情况下,随意修改类的内部实现,你可以把 String name 改为 String firstNameString lastName,但只要 getName()setName() 方法的行为保持一致,外部代码就无需改动。
  • 附加行为:可以在 setget 方法中添加日志、触发事件、计算派生值等。

setget 方法的命名规范

Java 社区有非常严格的命名规范,遵循这些规范能让你的代码更专业、更易读。

  • Getter 方法

    Java中set/get方法为何存在?-图3
    (图片来源网络,侵删)
    • 方法名以 get 开头。
    • 后面紧跟成员变量的首字母大写形式。
    • 返回类型:与成员变量的类型相同。
    • 参数:无。
    // 成员变量
    private String name;
    // Getter
    public String getName() {
        return this.name;
    }
  • Setter 方法

    • 方法名以 set 开头。
    • 后面紧跟成员变量的首字母大写形式。
    • 返回类型void
    • 参数:一个参数,类型与成员变量相同。
    // 成员变量
    private int age;
    // Setter
    public void setAge(int age) {
        this.age = age;
    }

特例:布尔类型的 Getter

对于 boolean 类型的成员变量,Getter 方法有一个更简洁的命名方式:

  • 标准方式isXxx()
  • 也可以使用 getXxx(),但 isXxx() 更常用、更符合直觉。
// 成员变量
private boolean isActive;
// Getter (推荐)
public boolean isActive() {
    return this.isActive;
}
// Getter (也可以,但不常用)
public boolean getActive() {
    return this.isActive;
}
// Setter (和普通类型一样)
public void setActive(boolean active) {
    this.isActive = active;
}

一个完整的示例

下面是一个完整的 Student 类,展示了如何正确地使用 private 成员变量和 publicset/get 方法,并在其中加入了数据验证逻辑。

public class Student {
    // 1. 将成员变量设为 private,实现封装
    private String studentId;
    private String name;
    private int age;
    private double score;
    // 2. 构造方法 (可选,但推荐)
    public Student(String studentId, String name, int age, double score) {
        this.studentId = studentId;
        this.setName(name); // 使用 setter 方法来复用验证逻辑
        this.setAge(age);   // 使用 setter 方法来复用验证逻辑
        this.setScore(score);
    }
    // 3. Getter 和 Setter 方法
    // Getter for studentId
    public String getStudentId() {
        return studentId;
    }
    // Setter for studentId (假设ID一旦创建不能修改)
    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }
    // Getter for name
    public String getName() {
        return name;
    }
    // Setter for name (带验证逻辑)
    public void setName(String name) {
        if (name == null || name.trim().isEmpty()) {
            System.out.println("错误:姓名不能为空!");
            // 可以选择抛出异常或者设置一个默认值
            // this.name = "未知";
            return;
        }
        this.name = name;
    }
    // Getter for age
    public int getAge() {
        return age;
    }
    // Setter for age (带验证逻辑)
    public void setAge(int age) {
        if (age < 0 || age > 120) {
            System.out.println("错误:年龄必须在 0 到 120 之间!");
            return;
        }
        this.age = age;
    }
    // Getter for score
    public double getScore() {
        return score;
    }
    // Setter for score (带验证逻辑)
    public void setScore(double score) {
        if (score < 0 || score > 100) {
            System.out.println("错误:分数必须在 0 到 100 之间!");
            return;
        }
        this.score = score;
    }
    // 一个普通方法,用于展示学生信息
    public void displayInfo() {
        System.out.println("学生信息:");
        System.out.println("  学号: " + this.getStudentId());
        System.out.println("  姓名: " + this.getName());
        System.out.println("  年龄: " + this.getAge());
        System.out.println("  分数: " + this.getScore());
    }
}

如何使用这个类:

public class Main {
    public static void main(String[] args) {
        // 创建一个合法的学生对象
        Student student1 = new Student("S001", "张三", 20, 95.5);
        student1.displayInfo();
        System.out.println("--------------------");
        // 尝试修改学生信息,使用 setter 方法
        student1.setAge(21);
        student1.setScore(88.0);
        student1.displayInfo();
        System.out.println("--------------------");
        // 尝试设置非法数据,setter 方法会进行拦截
        student1.setAge(-5);      // 会打印错误信息
        student1.setScore(150);   // 会打印错误信息
        student1.setName("");     // 会打印错误信息
        // 数据没有被修改
        student1.displayInfo();
    }
}

输出结果:

学生信息:
  学号: S001
  姓名: 张三
  年龄: 20
  分数: 95.5
--------------------
学生信息:
  学号: S001
  姓名: 张三
  年龄: 21
  分数: 88.0
--------------------
错误:年龄必须在 0 到 120 之间!
错误:分数必须在 0 到 100 之间!
错误:姓名不能为空!
学生信息:
  学号: S001
  姓名: 张三
  年龄: 21
  分数: 88.0

现代 Java 中的 setget:Lombok

虽然手动编写 setget 方法是理解其原理的最佳方式,但在实际开发中,一个类往往有很多成员变量,手动编写这些重复的代码会非常繁琐。

为了解决这个问题,像 Lombok 这样的库应运而生,Lombok 通过注解,可以在编译时自动为你的类生成 settergettertoString()equals()hashCode() 等样板代码。

使用 Lombok,上面的 Student 类可以简化为:

import lombok.Getter;
import lombok.Setter;
@Getter // 为所有 private 成员变量生成 getter
@Setter // 为所有 private 成员变量生成 setter
public class StudentLombok {
    private String studentId;
    private String name;
    private int age;
    private double score;
    // 构造方法
    public StudentLombok(String studentId, String name, int age, double score) {
        this.studentId = studentId;
        this.name = name;
        this.age = age;
        this.score = score;
    }
    // 你仍然可以手动定义某个 setter 来加入特殊逻辑
    @Setter
    public void setAge(int age) {
        if (age < 0 || age > 120) {
            System.out.println("错误:年龄必须在 0 到 120 之间!");
            return;
        }
        this.age = age;
    }
    // ... 其他方法
}

注意:使用 Lombok 需要在你的 IDE(如 IntelliJ IDEA 或 Eclipse)中安装插件,并在项目中添加 Lombok 的依赖。


特性 描述
目的 实现封装,保护对象内部数据,提供受控的访问方式。
命名 getXxx() / setXxx(),布尔类型可用 isXxx()
关键字 成员变量为 privateset/get 方法为 public
核心优势 数据验证:确保数据合法性。
灵活性:内部实现可变,外部接口不变。
安全性:防止非法访问和修改。
附加行为:可在访问时添加日志、计算等逻辑。
现代实践 手动编写以学习原理,在实际项目中使用 Lombok 等工具提高效率。

掌握 setget 方法是迈向专业 Java 开发者的第一步,它体现了面向对象设计的精髓。

分享:
扫描分享到社交APP
上一篇
下一篇