【问题标题】:Why are getter and setter method important in java? [duplicate]为什么getter和setter方法在java中很重要? [复制]
【发布时间】:2023-03-09 07:21:01
【问题描述】:

我被教导要始终使用 getter 和 setter。但是,我不知道这些方法的优缺点,因为通过实施它们,我们既暴露了数据又隐藏了它。

我对此有点困惑。任何人都可以就我们为什么使用 getter/setter 以及优势是什么提供一些适当的建议吗?

【问题讨论】:

    标签: java methods getter-setter


    【解决方案1】:

    在封装方面,基本的“具有公共 getter 和 setter 的私有字段,除了返回或设置字段什么都不做”模式确实完全没有意义,只是它让您有机会在不更改 API 的情况下稍后更改它。

    所以不要不假思索地使用这种模式。仔细考虑您实际需要哪些操作。

    getter 和 setter 的真正意义在于,您应该只在适当的地方使用它们,并且它们可以做的不仅仅是获取和设置字段。

    • 您只能有一个吸气剂。然后该属性是只读的。这实际上应该是最常见的情况。
    • 您可以只有一个 setter,使属性可配置,但传达的信息不应依赖于它的值
    • getter 可以从多个字段计算一个值,而不是返回一个字段。
    • getter 可以制作防御性副本
    • getter 可以延迟执行昂贵的 fetch 操作并使用字段来缓存值
    • 二传手可以进行健全性检查并抛出IllegalArgumentException
    • setter 可以通知监听器值的变化
    • 您可以有一个 setter 将多个字段设置在一起,因为它们在概念上属于一起。这不符合 JavaBeans 规范,因此如果您依赖需要 JavaBeans 的框架或工具,请不要这样做。否则,这是一个有用的选择。

    所有这些都是隐藏在简单的“getter and setter”接口后面的实现细节。这就是封装的意义所在。

    【讨论】:

    • 这是一个很好的答案。我觉得“始终在私有字段周围使用 getter/setter”的教条促成了 Java 臃肿的声誉。控制对字段的访问以及对设置或获取字段做出反应的能力应该是语言的一部分并封装在类实现中。
    【解决方案2】:

    这是缺点。 Getters/Setters 倾向于将你的类的实现细节暴露给外界。这不是一件好事。想象一下,您正在编写一个汽车机械师软件包。因此,您将需要一个 Car 类,并为这些字段公开 getter 和 setter

    Date lastOilChangeDate;
    int lastOilChangeMileage;
    

    在这个班级。这是因为该软件希望在客户汽车需要换油时发送电子邮件。

    但是当新车问世时,您确定汽车是否需要换油,而不是“每 3000 英里或 3 个月”换油?也许这些新车的油底壳里有一个传感器来测量脏度。显然,您希望使用它来确定是否需要更换机油。

    问题是您使用这些 getter/setter 解决了错误的问题。没有人真的想知道最后一次换油是什么时候,他们想知道您是否需要另一次换油。它们只是实现细节,但您使它们成为接口的一部分。你应该做的是添加一个方法

    public boolean needsOilChange() 
    

    然后 Car 类可以实现它想要的任何方式。如果算法发生改变,Mechanic 类就不必改变,因为它只需要 needsOilChange 方法。

    【讨论】:

    • Getter 和 setter 只有在你故意这样写时才会暴露实现细节。
    • 汽车无法确定是否需要换油。这是由机械师进行一些分析或遵循一些指导方针来确定的。您的 needsOilChange() 方法属于其他对象。任何数量的应用程序都可能会发现知道最后一次换油的日期和/或里程非常有用,这些是每辆车都有的属性。当然,除非我们正在考虑特斯拉。即便如此,我们可能希望再次保留换油的历史,即使这些细节也最好保留在其他地方......这里的重点是,这一切都取决于。教条是敌人。
    • 你的车太旧了
    【解决方案3】:

    这主要用于Java bean,如下所示。

    public Class MyBean{

    private int var1;

    public void setVar1(int pVar1){

    this.var1=pvar1;

    }

    public int getVar1(){

    返回 var1;`

    }

    }

    好处如下

    1.这样我们就可以实现封装

    2.它被称为DTO(数据传输对象)设计模式。 它用于在基于 MVC 的应用程序中将数据从一层传输到另一层。 就像你可以从表单中获取用户输入的数据(通过使用getter),你可以使用相同的数据插入数据库(通过使用setter),反之亦然。 最新的框架 (SPring) 将其作为内置功能提供。

    【讨论】:

    • 很抱歉,但我认为这不是一个好的答案(代码也不是很好的编写或格式)。第 1 点是完全错误的,使用 getter 和 setter 并不能帮助您实现封装。第 2 点关于将 Java bean 用作 DTO 是正确的,但问题是关于 getter/setter 的使用,bean 使用这些并不意味着使用 DTO 是 getter/setter 的好处。恐怕我是-1,尽管是公认的答案。
    • 如果你没有限制地对每个变量使用 getter 和 setter,你就没有封装任何东西。
    • getter 和 setter 是 Java bean 的一部分,Java bean 是 DTO,那么根据传递规律,DTO 是 getter 和 setter 的好处。
    • 不,Java bean 不是 DTO。 JavaBeans 背后的最初想法是让组件具有大量逻辑和功能,通过 getter 和 setter 公开配置选项。 Swing 组件就是这样设计的 JavaBeans。
    • 最初的想法可能是Java bean可以用作DTO,我就是这样做的
    【解决方案4】:

    使用 getter 和 setter 并没有错 - 只需注意通过 使用它们并将它们全部公开,你就暴露了你的变量,并且在某种程度上,违反封装。这就是您提到的文章试图警告的内容-不要只是为所有私有实例变量自动生成getter和setter;考虑一下您想向其他类公开什么(以及在什么级别,即私有/受保护/公共),以便仅在需要时公开。

    【讨论】:

      【解决方案5】:

      getter 和 setter 的想法是控制对类中变量的访问。这样,如果需要在内部更改值以以不同的方式表示,您可以这样做而不会破坏类外的任何代码。

      例如,假设您有一个带有距离变量的类,它以英寸为单位。几个月过去了,你在很多地方都在使用这个类,你突然意识到你需要用厘米来表示这个值。如果您不使用 getter 和 setter,则必须跟踪该类的每次使用并在那里转换。如果您使用了 getter 和 setter,您只需更改这些方法,使用该类的所有内容都不会中断。

      public class Measurement
      {
      
          /**
           * The distance in centimeters.
           */
          private double distance;
      
          /**
           * Gets the distance in inches.
           * @return A distance value.
           */
          public double getDistance()
          {
              return distance / 2.54;
          }
      
          /**
           * Sets the distance.
           * @param distance The distance, in inches.
           */
          public void setDistance(double distance)
          {
              this.distance = distance * 2.54;
          }
      }
      

      【讨论】:

      • 啊啊啊啊啊!就是这样了!如果您必须以不同的方式表示数据,并且您将在许多其他类中使用变量,则只需更改设置方法中的实现将更改所有其他类中的变量。很好。然后我认为对您经常使用的变量使用 setter 方法是一种很好的编程,因为您以后可能必须更改它?我们应该多久使用一次 setter 和 getter?
      • 这是一个很好的例子!
      • 跟踪甚至重构使用公共字段的类的每次使用都一点都不难,尤其是在现代 IDE 中。只需将该字段设为私有,让编译器为您完成繁重的工作。至于几个月后会发生什么,人们可能会争论 YAGNI。只是说..
      【解决方案6】:

      想到的一个好处是,您可以通过不为特定字段实现设置器来使字段ReadOnly。

      【讨论】:

        猜你喜欢
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-18
        • 1970-01-01
        • 1970-01-01
        • 2010-11-30
        • 1970-01-01
        相关资源
        最近更新 更多