杰瑞科技汇

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

封装

在深入 setget 之前,必须理解它们背后的设计原则——封装

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

封装是面向对象的三大特性之一(封装、继承、多态),它的核心思想是:

  1. 隐藏内部实现:类的内部数据(字段/属性)不应该被外部直接访问和修改。
  2. 提供公共接口:通过公共的方法(即 getset 方法)来控制对内部数据的访问和修改。

为什么需要封装?

  • 数据安全:防止外部代码随意修改对象的状态,导致对象处于一个无效或不一致的状态。
  • 灵活性:可以在 set 方法中加入逻辑检查(比如年龄不能为负数),或者在进行 get 操作时进行计算(比如计算折扣后的价格),而不会影响到调用这些方法的代码。
  • 维护性:如果类的内部实现需要改变(比如一个字段 String name 改为 FullName 对象),只需要修改 getset 方法的内部逻辑,所有调用这些方法的代码都不需要改变。

get 方法

get 方法是“获取”方法,用于获取对象的私有字段的值。

语法规范

// 1. 访问修饰符通常是 public
// 2. 方法名通常是 "get" + 字段名(首字母大写)
// 3. 没有参数
// 4. 返回值类型与字段类型一致
public <返回值类型> get<字段名首字母大写>() {
    return this.<字段名>;
}

示例

假设我们有一个 Student 类,其中有一个私有字段 name

Java中set/get方法究竟该怎么用?-图2
(图片来源网络,侵删)
public class Student {
    // 1. 私有化字段,外部无法直接访问
    private String name;
    // 2. 提供 public 的 get 方法来获取 name 的值
    public String getName() {
        return this.name;
    }
}

如何使用 get 方法:

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        // student.name = "张三"; // 错误!name 是私有的,无法直接访问
        // 通过 get 方法获取 name 的值
        // 假设我们通过其他方式(比如构造函数)设置了 name
        student.setName("张三"); // 我们稍后会讲到 set 方法
        String studentName = student.getName(); // 正确!调用 get 方法
        System.out.println("学生姓名是: " + studentName); // 输出: 学生姓名是: 张三
    }
}

set 方法

set 方法是“设置”方法,用于修改对象的私有字段的值。

语法规范

// 1. 访问修饰符通常是 public
// 2. 方法名通常是 "set" + 字段名(首字母大写)
// 3. 有一个参数,参数类型与字段类型一致
// 4. 返回值类型通常是 void
public void set<字段名首字母大写>(<参数类型> <参数名>) {
    this.<字段名> = <参数名>;
}

示例

继续使用 Student 类,我们为 name 字段添加一个 set 方法。

public class Student {
    private String name;
    // get 方法
    public String getName() {
        return this.name;
    }
    // set 方法
    public void setName(String name) {
        // 可以在这里添加逻辑,确保数据的有效性
        // 不允许设置空名
        if (name != null && !name.trim().isEmpty()) {
            this.name = name;
        } else {
            System.out.println("姓名不能为空!");
        }
    }
}

如何使用 set 方法:

Java中set/get方法究竟该怎么用?-图3
(图片来源网络,侵删)
public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        // 通过 set 方法设置 name 的值
        student.setName("李四");
        System.out.println("学生姓名是: " + student.getName()); // 输出: 学生姓名是: 李四
        // 尝试设置一个无效的值
        student.setName(""); // 输出: 姓名不能为空!
        System.out.println("学生姓名仍然是: " + student.getName()); // 输出: 学生姓名仍然是: 李四
    }
}

从上面的例子可以看出,set 方法提供了一个“关卡”,可以确保 name 字段不会被设置为无效的值。


一个完整的 Student 类示例

下面是一个包含私有字段、构造函数、getset 方法的完整类。

public class Student {
    // 私有字段
    private String name;
    private int age;
    private boolean isMale; // 性别
    // 构造函数,用于在创建对象时初始化字段
    public Student(String name, int age, boolean isMale) {
        this.name = name;
        this.age = age;
        this.isMale = isMale;
    }
    // --- Getter and Setter Methods ---
    // name 的 get 和 set
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // age 的 get 和 set
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        // 在 set 方法中加入业务逻辑,确保数据合理性
        if (age > 0 && age < 120) {
            this.age = age;
        } else {
            System.out.println("年龄必须在 1 到 119 之间!");
        }
    }
    // isMale 的 get 和 set
    // 对于 boolean 类型,get 方法通常命名为 "is" 而不是 "get"
    public boolean isMale() {
        return isMale;
    }
    public void setMale(boolean male) {
        isMale = male;
    }
    // 一个普通的方法,用于打印学生信息
    public void printInfo() {
        System.out.println("姓名: " + name + ", 年龄: " + age + ", 性别: " + (isMale ? "男" : "女"));
    }
}

使用这个完整类:

public class Main {
    public static void main(String[] args) {
        // 使用构造函数创建学生
        Student student1 = new Student("王五", 20, true);
        student1.printInfo(); // 输出: 姓名: 王五, 年龄: 20, 性别: 男
        // 使用 set 方法修改年龄
        student1.setAge(21);
        student1.printInfo(); // 输出: 姓名: 王五, 年龄: 21, 性别: 男
        // 尝试设置一个无效的年龄
        student1.setAge(-5); // 输出: 年龄必须在 1 到 119 之间!
        student1.printInfo(); // 年龄没有被修改,输出: 姓名: 王五, 年龄: 21, 性别: 男
        // 使用 get 方法获取信息
        System.out.println("学生 " + student1.getName() + " 的年龄是 " + student1.getAge());
    }
}

最佳实践和注意事项

  1. 私有化所有字段:总是将类的字段声明为 private
  2. 为每个私有字段提供 getset 方法:除非有特殊理由(比如只读字段,可以只提供 get 方法)。
  3. 布尔类型的 get 方法:对于 boolean 类型的字段,get 方法通常命名为 isXxx() 而不是 getXxx()isActive() 而不是 getActive(),IDE(如 IntelliJ IDEA)在自动生成时会遵循这个规范。
  4. 使用 Lombok(推荐):在实际开发中,编写大量的 getset 方法是重复且繁琐的,可以使用 Lombok 库通过一个简单的注解 @Data@Getter/@Setter 来自动生成这些方法,让代码更简洁。

使用 Lombok 的示例:

确保你的项目中已经添加了 Lombok 依赖。

import lombok.Data;
@Data // @Data 会自动为所有非静态字段生成 get, set, toString, equals, hashCode 方法
public class Student {
    private String name;
    private int age;
    private boolean isMale;
}
// 使用方式完全一样,但代码量大大减少
public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("赵六");
        student.setAge(22);
        System.out.println(student.getName()); //赵六
    }
}
特性 get 方法 set 方法
目的 获取私有字段的值 设置私有字段的值
方法名 getFieldName()isFieldName() (布尔) setFieldName()
参数 一个,类型与字段相同
返回值 字段的类型 void
核心作用 提供对私有数据的只读访问 提供对私有数据的受控写入

掌握 setget 方法是理解 Java 面向对象编程的基石,它体现了封装这一重要设计原则,是编写健壮、可维护代码的关键。

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