当前位置: 首页 > 知识库问答 >
问题:

在java中,为什么将同时具有setter和getter的字段设置为公共字段不好?[重复]

娄阳舒
2023-03-14

请考虑以下 Java 代码:

public class SomeClass{  
    private int data;  
    public void setData(int data){  
        this.data = data;  
    }  
    public int getData(){  
        return this.data;  
    }
}

在上面的代码中,可以从任何地方访问数据的值。那么,为什么不将现场数据公开呢?

共有3个答案

桓高澹
2023-03-14

即使现在看起来使用getter/setter方法没有意义,因为它们没有做任何有趣的事情,您也需要考虑将来当需求改变时会发生什么。您可能会发现在设置值时需要添加一些验证;您可能会发现,您需要更改整个实现,以便“get”方法实际上是要从几段数据中计算一个值,或者从一个文件中读取它,等等。当这种情况发生时,如果你有其他类直接访问< code >数据,你就完蛋了。你将无法按照你需要的方式改变实现,而不会有太多的痛苦。我是从长期痛苦的经历中说这番话的,我经历了维护他人草率代码的痛苦。

申自明
2023-03-14

因为您可以控制其他类如何设置数据。

您可以预先对输入进行检查,甚至可以根据您可能拥有的某些规则修改输入。

例如:

public class SomeClass{  
private int data;  
public void setData(int data){  
    if (data < 1000){
        this.data = data;  
    }
    else{
        data = -1;
    }
}  
public int getData(){  
    return this.data;  
}

}

慕宜民
2023-03-14

为什么是能手和二传手?

许多人想知道为什么我们需要Java中的访问器和赋值器方法(又名getters和setters),为什么我们不能直接访问数据?但这里封装的目的不是隐藏数据本身,而是关于如何操作这些数据的实现细节。因此,我们再次想要的是一种提供公共接口的方法,通过该接口我们可以访问这些数据。稍后我们可以在不影响类的公共接口的情况下更改数据的内部表示形式。相反,通过公开数据本身,我们损害了封装,因此,在不影响其用户的情况下,将来更改操作此数据的方式的能力。我们将创建一个与数据本身的依赖关系,而不是与类的公共接口的依赖关系。当“改变”最终找到我们时,我们将为麻烦创造一种完美的鸡尾酒。

有几个令人信服的原因,为什么我们可能想要封装对我们字段的访问。我所能找到的这些原因的最好纲要在Joshua Bloch的书《Effective Java》中有所描述。在项目14:最小化类和成员的可访问性中,他提到了几个原因,我在这里提到:

  • 您可以限制可以存储在字段中的值(即性别必须为 F 或 M)。
  • 您可以在修改字段时执行操作(触发事件、验证等)。
  • 您可以通过同步该方法来提供线程安全。
  • 您可以切换到新的数据表示形式(即计算字段,不同的数据类型)
  • 您可以将字段设置为只读
  • 等。

然而,理解封装不仅仅是隐藏字段是非常重要的。在Java中,我们可以隐藏整个类,从而隐藏整个API的实现细节。

通过阅读Alan Snyder的一篇名为《面向对象编程语言中的封装和继承》的文章,我对这个重要概念的理解得到了扩展和丰富,我向所有读者推荐了这篇文章。

 类似资料:
  • 我想完成但不明白它是如何工作的 使用这段代码,我想注释生成它们各自的setter和getter,这样我就可以使用像 编辑2013-10-25 我的目标是构建一个能够做到这一点的库,因为我太好奇了,想了解如何在内部工作,所以我将能够用这个特性来支持我的框架,因为jet只是一个小实用程序,但在未来我希望它能为我节省大量的工作,你可以在github WSD Android上看到

  • 问题内容: 我有一个示例类,如下所示: 稍后,当我尝试这样做时: 我收到一条错误消息,说名称字段不存在。为什么? 问题答案: 因为 类型 的变量是(在 运行时类型 的的 对象 ,在所述变量是实现匿名类的这也是一个 亚型 的)… …并且该类型没有该成员。因此,出现编译错误。(请记住,该变量可以包含符合的任何对象,即使没有的对象也是如此,因此编译器会拒绝不是类型安全的代码。) 编辑:对于一种解决方案,

  • Spring Roo有一个@RooJavaBean注释,它为非瞬态字段生成AsheJ getter和setter。问题是它也为瞬态字段生成它们。我在Asset.java中有这个: 我有以下Asset_Roo_JavaBean.aj: 即使一个字段是暂时的,我想您仍然可以使用getter和setter访问它,但是为什么文档会对gettersByDefault注释字段这样说呢 是否为此类中声明的每个非

  • 问题内容: 在golang中,有没有办法查看是否可以将解编入结构的json字段与设置为null的json字段区分开?因为两者都将struct中的值设置为nil,但是我需要知道字段是否以该字段开头,并查看是否有人将其设置为null。 VS 当解组为结构时,两个json均为零。任何有用的资源将不胜感激! 问题答案: 使用以“拖延”解组过程决定做某件事之前要确定原始字节: 参观游乐场https://pl

  • 问题内容: 为什么Java有瞬态字段? 问题答案: 在中关键字用于指示字段不应该是系列化的一部分(这意味着保存,像一个文件)的过程。 从Java语言规范,Java SE 7中版,第8.3.1.3节。transient领域: 可以标记变量transient以指示它们不是对象持久状态的一部分。 例如,你可能具有从其他字段派生的字段,并且仅应以编程方式进行操作,而不要通过序列化来保持状态。 这是一个包含

  • 我现在在这里读到,为了实现我的目标的不变性,我必须: 宣布我的所有字段为私有和最终 不定义设定者 如果没有setter,为什么我需要声明字段是最终的。java编译器不允许这样的事情: 如果我尝试使用反射,那么关键字不会阻止我更改引用。 我在这里找到了一个很好的解释,为什么整个类需要是,但没有解释为什么私有字段需要是final。 编辑:作为对GotoFinal评论的回复,这里有一个类展示了我如何通过