Getter and Setter Method in Java Example

2025年5月8日 | 阅读 9 分钟

Getter 和 Setter 方法在 Java 编程中经常使用。Java 中的 Getter 和 Setter 方法广泛用于访问和操作类字段的值。通常,类字段会用 private 访问修饰符进行声明。因此,为了访问它们,会使用 public 访问修饰符配合 getter 和 setter 方法。

Getter 和 Setter 方法的必要性

有人可能会争辩说,可以将类字段声明为 public 并移除 getter 和 setter 方法。然而,这种编码风格是不好的,并且可能会给类字段设置一些不合理的值。让我们通过一个例子来理解这一点。

请注意,代码将负薪水存储在数据库中,这是错误的。组织绝不会向员工账户支付负薪水。向 salary 变量分配一个不合理的值是因为它被声明为 public 访问修饰符。编写上述代码的正确方法是:

现在,我们可以更好地控制要发送到数据库存储的内容。每当薪水为负时,我们都会将其转换为正值,然后将其发送到数据库进行存储。因此,无论我们向 setter 方法发送什么值,setter 方法的 if 块都会处理不合理的值,从而更好地控制薪水值。

Getter Setter Java 程序

文件名: GetterSetterExample1.java

输出

Employee: [id = 107, name = Kathy, designation = Software Tester, company = XYZ Corporation]

Getter 和 Setter 方法中的不良实践

人们在处理 getter 和 setter 方法时,通常会犯一些常见的错误。

不良实践 1

为具有低限制性范围的变量使用 getter 和 setter。

从 main 方法中,可以显式地访问变量 salary,这不仅不好,而且使 getter 和 setter 方法的存在变得无关紧要。

不良实践 2

在 setter 方法中使用对象引用。考虑以下程序。

文件名: GetterSetterExample2.java

输出

3 4 6 8 78 9 
-1 4 6 8 78 9

解释

引用稍微棘手!在上面的代码中,在第 43 行,数组 mainArr[] 的第 0 个索引处更新了值。然而,它也反映在数组 val[] 中。这本不应该发生,因为 val[] 数组被声明为 private;因此,预期类 ABC 之外的任何代码都不应修改它。然而,由于引用,一切都被搞乱了。setter 方法 setVal() 期望一个 int 数组的引用,而在第 7 行,int arr[] 的引用被复制到 val[]。请注意,引用变量 arr[] 存储了 mainArr[] 数组的引用。因此,我们可以说 val[] 存储了 mainArr[] 的引用。

因此,无论我们在 mainArr[] 中做什么更改,都会反映在 val[] 数组中,这违反了 setter 方法的目的。此外,为 val[] 数组添加 private 访问修饰符也没有意义;因为可以在 main 方法中更改 val[] 数组的值,这一点从输出中可以明显看出。

编写上述代码的更好方法是:

文件名: GetterSetterExample3.java

输出

3 4 6 8 78 9 
3 4 6 8 78 9 

解释

在上面的代码中,我们对数组 arr[] 的元素进行了深拷贝。在第 11 行,我们创建了一个全新的数组。因此,val[] 不引用 arr[]。此外,在第 17 行,只复制了元素的值。因此,当我们在第 53 行更改第 0 个元素的值时,更改不会反映在 val[] 中。因此,上面的代码遵守了 private 成员变量 val[] 的封装。

不良实践 3

在 getter 方法中返回一个对象引用。请注意以下程序。

文件名: GetterSetterExample4.java

输出

67 43 68 112 70 12 
-1 43 68 112 70 12

解释

上面的代码没有正确处理引用。getter 方法返回数组的引用。arr[] 存储了 val[] 数组的引用,该数组在类 ABC 中被声明为 private。由于将引用暴露给外部世界,arr[] 可以操纵 val[],从而违反了类 ABC 的封装。处理上述问题的正确方法是:

文件名: GetterSetterExample5.java

输出

67 43 68 112 70 12 
67 43 68 112 70 12

解释: 在上面的代码中,私有数组的引用没有传递给外部世界。在 getter 方法中,创建了一个新数组,其引用被传递给 main 方法。因此,当第 54 行的第 0 个索引处的值更改时,该更改会影响 temp[] 数组,而不是私有数组 val[]。因此,类 ABC 的封装得到了维护,因为数组 val[] 的引用没有暴露给外部世界。

注意 1:对于原始数据类型(int、char 等),不需要在 getter 和 setter 方法中创建副本,因为原始数据类型不存在引用的概念。

注意 2:String 对象类型也基于引用工作。然而,与上面的示例不同,您不必担心暴露给外部世界的 String 引用。这是因为 String 是不可变的。因此,当您在 main 方法(或任何其他地方)中操作 String 时,会创建一个新的 String 对象,而以前的对象保持不变。

文件名: GetterSetterExample6.java

输出

The String is: Hello India!
The String is: Hello India!