杰瑞科技汇

Java中get和set方法究竟该怎么用?

这不仅仅是一个语法问题,更是一种核心的编程思想——封装

Java中get和set方法究竟该怎么用?-图1
(图片来源网络,侵删)

为什么需要 getset 方法?

想象一下你在写一个 Student 类,用来表示一个学生:

public class Student {
    public String name;
    public int age;
}

你可以这样使用它:

Student student = new Student();
student.name = "张三";
student.age = -5; // 问题出现了!年龄可以是负数吗?

上面的代码中,student.age = -5 显然是不合逻辑的,但我们无法在 Student 类内部阻止这种不合理的赋值,这就是直接暴露成员变量的弊端。

getset 方法就是为了解决这个问题而生的,它们是实现封装 的标准方式。

Java中get和set方法究竟该怎么用?-图2
(图片来源网络,侵删)

封装的核心思想:

  1. 隐藏内部实现:类的内部数据(成员变量)不应该被外部直接访问和修改。
  2. 提供受控的访问:通过公共的方法(getset)来暴露对数据的操作,这样我们可以在方法内部添加逻辑,确保数据的有效性和安全性。

getset 方法的命名和语法

语法规范

  • set 方法 (Setter / Mutator - 设置器/修改器)

    • 作用:用于给成员变量赋值。
    • 命名:通常以 set 开头,后跟成员变量的首字母大写的名称,变量是 name,方法就叫 setName
    • 参数:必须有一个参数,参数类型与成员变量类型相同,参数值就是我们要设置的值。
    • 返回值:通常是 void
    public void set成员变量类型 成员变量名(成员变量类型 参数名) {
        // 赋值逻辑
        this.成员变量名 = 参数名;
    }
  • get 方法 (Getter / Accessor - 访问器)

    • 作用:用于获取成员变量的值。
    • 命名:通常以 get 开头,后跟成员变量的首字母大写的名称,变量是 name,方法就叫 getName
    • 参数:通常没有参数。
    • 返回值:返回成员变量的类型。
    public 成员变量类型 get成员变量名() {
        // 返回逻辑
        return this.成员变量名;
    }

注意:对于布尔类型的成员变量,get 方法有时会遵循一个特殊的命名规范,用 is 代替 getboolean isPassed,其 get 方法可以命名为 isPassed(),但这不是强制性的,getPassed() 也是可以的。

Java中get和set方法究竟该怎么用?-图3
(图片来源网络,侵删)

代码示例

我们用 getset 方法来重构之前的 Student 类:

public class Student {
    // 1. 成员变量设为 private,禁止外部直接访问
    private String name;
    private int age;
    // 2. 提供 public 的 get 和 set 方法
    // name 的 get 方法
    public String getName() {
        return this.name;
    }
    // name 的 set 方法
    public void setName(String name) {
        // 可以在这里添加逻辑,比如不允许 name 为 null 或空字符串
        if (name != null && !name.trim().isEmpty()) {
            this.name = name;
        } else {
            System.out.println("姓名不能为空!");
        }
    }
    // age 的 get 方法
    public int getAge() {
        return this.age;
    }
    // age 的 set 方法,加入数据校验逻辑
    public void setAge(int age) {
        // 确保年龄在合理范围内
        if (age > 0 && age < 120) {
            this.age = age;
        } else {
            System.out.println("年龄必须在 1 到 119 岁之间!");
        }
    }
}

我们再来看如何使用这个改进后的 Student 类:

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        // 使用 set 方法赋值
        student.setName("李四");
        student.setAge(20); // 合法
        // 尝试设置非法值
        student.setAge(-5); // 会打印 "年龄必须在 1 到 119 岁之间!"
        student.setName(""); // 会打印 "姓名不能为空!"
        // 使用 get 方法获取值
        System.out.println("学生姓名: " + student.getName()); // 输出 "学生姓名: 李四"
        System.out.println("学生年龄: " + student.getAge());   // 输出 "学生年龄: 20" (非法赋值失败,年龄未被修改)
    }
}

通过这种方式,我们成功地控制了对 nameage 的访问,保证了数据的合法性。


getset 方法的好处总结

  1. 数据校验:可以在 set 方法中添加校验逻辑,防止非法数据被赋值(如年龄为负数、分数超过100等)。
  2. 封装性:隐藏了类的内部实现细节,未来如果 Student 类的 name 存储方式变了(比如从 String 变成了 IDDisplayName 的组合),我们只需要修改 Student 类内部的 getset 方法,而所有使用这个类的代码都不需要改动,这大大提高了代码的可维护性。
  3. 控制读写权限
    • 如果一个成员变量只希望被读取,不希望被修改,可以只提供 get 方法,不提供 set 方法。
    • 如果一个成员变量不希望被外部访问,可以既不提供 get 也不提供 set 方法。
  4. 附加逻辑:可以在 getset 方法中执行额外的操作。
    • get 示例:每次获取 salary 时,可以自动计算并加上奖金。
    • set 示例:每次设置 password 时,可以自动进行加密处理。

现代 Java 中的 getset

虽然手动编写 getset 方法是基础,但在实际开发中,我们通常会使用一些工具来自动生成它们,以减少重复劳动。

使用 IDE(如 IntelliJ IDEA, Eclipse)生成

几乎所有现代 Java IDE 都支持一键生成 getset 方法。

  • IntelliJ IDEA: 在代码编辑区右键 -> Generate -> Getter and Setter... -> 选择要生成的变量 -> 点击 OK
  • Eclipse: 在代码编辑区右键 -> Source -> Generate Getters and Setters... -> 选择变量 -> 点击 Generate

IDE 会自动遵循命名规范,并处理好 this 关键字。

使用 Lombok 库(非常流行)

Lombok 是一个 Java 库,它通过注解的方式,在编译时自动为你的类生成 getsettoString()equals()hashCode() 等样板代码。

使用 Lombok 可以让你的代码变得极其简洁。

你需要在项目中添加 Lombok 依赖(在 Maven 的 pom.xml 中):

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version> <!-- 使用最新版本 -->
    <scope>provided</scope>
</dependency>

你的 Java 类可以这样写:

import lombok.Getter;
import lombok.Setter;
@Getter // 为所有 private 成员变量自动生成 get 方法
@Setter // 为所有 private 成员变量自动生成 set 方法
public class Student {
    private String name;
    private int age;
}

或者,你可以更精细地控制,只为特定变量生成:

import lombok.Getter;
import lombok.Setter;
public class Student {
    @Getter // 只为 name 生成 get 方法
    private String name;
    @Setter // 只为 age 生成 set 方法
    private int age;
}

使用方式完全一样,但你的源代码却无比清爽。


特性 手动编写 get/set 使用 Lombok
代码量 多,有大量样板代码 极少,代码简洁
可读性 方法分散,类可能很长 集中关注业务逻辑
IDE 支持 完美支持 完美支持,需要安装 Lombok 插件
学习曲线 基础,必须掌握 需要学习 Lombok 注解
灵活性 最高,可以编写任意复杂逻辑 较高,但局限于 Lombok 提供的功能
  • 对于初学者必须学会手动编写 getset 方法,并深刻理解其背后的封装思想,这是 Java 面向对象编程的基础。
  • 对于实际项目开发:强烈推荐使用 Lombok 来提高开发效率,减少重复代码,但在面试或笔试中,面试官很可能会要求你手写 getset 方法来考察你的基本功。
分享:
扫描分享到社交APP
上一篇
下一篇