为什么 getter 和 setter 方法在 java 中很重要?

发布于 2024-12-26 02:51:40 字数 133 浏览 1 评论 0原文

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

我对此有点困惑。任何人都可以就我们为什么使用 getter/setter 及其优点给出一些正确的建议吗?

I have been taught to always use getters and setters. However, I don't know the pros and cons of these methods, as by implementing them we are exposing the data and also hiding it.

I am a little confused about this. Can anybody give some proper advice on why we use a getter/setter and what the advantages are?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

萝莉病 2025-01-02 02:51:41

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

public Class MyBean{

private int var1;

public void setVar1(int pVar1){

this.var1=pvar1;

}

public int getVar1(){

return var1;`

}

}

好处如下

1. 有了这个我们可以实现封装

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

this is mostly used in Java beans like below.

public Class MyBean{

private int var1;

public void setVar1(int pVar1){

this.var1=pvar1;

}

public int getVar1(){

return var1;`

}

}

benefits are as below

1. with this we can achieve Encapsulation

2. it is called as DTO (Data Transfer Object) design pattern.
it is used to transfer data from one layer to another layer in MVC based applications.
like u can get user entered data from form (by using getters) and u can use the same data to insert into database(by using setter) and vice verca.
latest frameworks (SPring )providing it as inbuilt functionality.

囚我心虐我身 2025-01-02 02:51:40

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

因此,不要不假思索地使用该模式。仔细考虑您实际需要什么操作。

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

  • 你只能有一个吸气剂。那么该属性是只读的。这其实应该是最常见的情况。
  • 您可以只拥有一个 setter,使属性可配置,但传达出没有其他内容应该依赖于其值的信息。
  • getter 可以从多个字段计算一个值,而不是返回一个字段。
  • getter 可以创建防御性副本
  • getter 可以惰性地执行昂贵的获取操作并使用字段来缓存值
  • setter 可以进行健全性检查并抛出 IllegalArgumentException
  • setter 可以通知侦听器值的更改
  • 您可以使用一个设置器将多个字段设置在一起,因为它们在概念上属于在一起。这不符合 JavaBeans 规范,因此如果您依赖于需要 JavaBeans 的框架或工具,请不要这样做。否则,这是一个有用的选择。

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

The basic "private field with public getter and setter that do nothing but return or set the field" pattern is indeed completely pointless when it comes to encapsulation, except that it gives you a chance to change it later without changing the API.

So don't use that pattern unthinkingly. Carefully consider what operations you actually need.

The real point of getters and setters is that you should only use them where they are appropriate, and that they can do more than just get and set fields.

  • You can have only a getter. Then the property is read only. This should actually be the most common case.
  • You can have only a setter, making the property configurable, but communicating that nothing else should depend on its value
  • A getter can compute a value from several fields rather than return one field.
  • A getter can make a defensive copy
  • A getter can perform an expensive fetch operation lazily and use a field to cache the value
  • A setter can do sanity checks and throw IllegalArgumentException
  • A setter can notify listeners of changes to the value
  • You can have a setter that sets multiple fields together because they belong together conceptually. This doesn't adhere to the JavaBeans specification, so don't do it if you depend on frameworks or tools that expect JavaBeans. Otherwise, it's a useful option.

All of these things are implementation details that are hidden behind the simple "getter and setter" interface. That's what encapsulation is about.

阳光下慵懒的猫 2025-01-02 02:51:40

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;
    }
}

The idea of getters and setters are to control access to variables in a class. That way, if the value needs to be changed internally to be represented in a different way, you can do so without breaking any code outside the class.

For example, let's say you had a class with a distance variable, and it was measured in inches. A few months pass, you're using this class in a lot of places and you suddenly realize you needed to represent that value in centimeters. If you didn't use a getter and a setter, you would have to track down every use of the class and convert there. If you used a getter and a setter, you can just change those methods and everything that uses the class won't break.

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;
    }
}
云裳 2025-01-02 02:51:40

想到的一个很好的优点是,您可以通过不为特定字段实现设置器来将字段设置为只读

One good advantage comes into mind is that you can make a field ReadOnly by not implementing a setter for that particular field.

南七夏 2025-01-02 02:51:40

这是缺点。 Getters/Setters 倾向于向外界公开类的实现细节。这可不是什么好事。想象一下您正在编写一个汽车修理工软件包。因此,您将需要一个 Car 类,并为

Date lastOilChangeDate;
int lastOilChangeMileage;

该类中的字段公开 getter 和 setter。这是因为该软件希望在客户汽车需要更换机油时发送电子邮件。

但是,当新车问世时,您以不同于“每 3000 英里或 3 个月”的方式确定汽车是否需要更换机油,会发生什么情况呢?也许这些新车的油底壳里有一个传感器可以测量脏度。显然您想用它来确定是否需要更换机油。

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

public boolean needsOilChange() 

,然后 Car 类可以根据需要实现它。如果算法发生变化,Mechanic 类就不必这样做,因为它所需要的只是 needOilChange 方法。

Here's the downside. Getters/Setters tend to expose the implementation details of your class to the outside world. That's not a good thing. Imagine you are writing an Auto mechanic software package. Thus you will need a Car class, and so you expose getters and setters for the fields

Date lastOilChangeDate;
int lastOilChangeMileage;

in this class. This is because the software wants to send emails when customer cars need oil changes.

But what happens when new cars come out where you determine whether a car needs an oil change differently than 'every 3000 miles or 3 months'? Perhaps these new cars have a sensor in the oil pan that measured dirtyness. Obviously you'd want to use this to determine whether an oil change was needed.

The issue was you were solving the wrong problem with those getter/setters. No one really wants to know when the last oil change was, they want to know if you need another one. They were just implementation details, but you made them part of the interface. What you should have done was added a method

public boolean needsOilChange() 

and then the Car class could implement however it wanted. If the algorithm change the Mechanic class wouldn't have to because all it needed was the needsOilChange method.

最笨的告白 2025-01-02 02:51:40

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

There is nothing wrong with using getters and setters - just be aware that by using them and making them all public you're exposing your variables and, in a way, violating encapsulation. This is what the article you mention is trying to warn of - don't just automatically generate getters and setters for all private instance variables; think about what you want to expose to other classes (and at what level, i.e. private/protected/public) so that you're exposing only as needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文