开发者

Is there any benefit to using getters/setters inside a class for its own fields? [duplicate]

This question already has answers here: Is it in an anti-pattern to always use get and set methods to access a class's own member fields? [duplicate] (11 answers) Closed 9 years ago.

Usually, in my own p开发者_C百科rojects I use getters and setters for any field access, and I followed to do the same on my job. Some time ago, the tech lead of our project asked me why I was doing that and why is this better than just using fields themselves (with an option of declaring them protected if they needed to be accessed by subclasses). I couldn't come up with a clear answer.

So, are there any reasons to using getters and setters inside a class for class' own fields, or is it better to use fields directly?


The most obvious answer is side effects:

int getCost()
{
    if (cost == null) {
        calculateCost();
    }

    return cost;
}

If you need the cost, use getCost(). If you want to see if cost has been calculated, use cost.


If there is any business logic around those values (or there is the potential for such logic), then there is a benefit to using getters and setters even for internal calls.

For example, your setter might do validation on its inputs, and throw an exception rather than store an invalid value. Having all your code use that setter rather than simply setting values directly means that the error is caught at the time it is made rather than a long time later when that value is used. A similar case for a getter is when there is a logical default value, which should be used in case of a null. By using a getter, you can safely write local methods without needing continuous null checks or default options.

That said, if there's no business logic in those methods, and no side effects caused by them, then it's mostly a stylistic thing. It is essentially the responsibility of the class to be internally consistent, and as long as it remains so then it's mostly personal/professional preference whether you access the variables directly or through wrapping methods.


You want to declare them as public getters and setters, and private fields. This means external classes (not subclasses) who want to modify the variables all do so through the setters, and get them through the getters. The benefit of this is that if you want to control how or what condition they get or set them, or want to add information or even print debug, it means you only have to put it in the getters and setters.

There's a really good explanation of the benefits on stackoverflow actually:

In Java, difference between default, public, protected, and private

Of course, only make methods when they're actually needed, and similarly, only public when needed by external classes.

Hope that helps the defense!


This is part of the general question as to why you use getters and setters. Many developers use them without though, as a matter of practice. Personally, I only put in getters/setters if I need to.

I would suggest you do what is clearest/simplest to you.

In general, if I can easily add a getter/setter later should I need it, I won't add it. If it would be difficult to add later (or you have an immediate use for them), I would include them.


Some of us are web developers so, we resort to creating JavaBeans and JavaBeans has its own specification. In the specification, it clearly states:

  • The class must have a public default constructor (no-argument).
  • The class properties must be accessible using get, set, is (used for boolean properties instead of get) and other methods.
  • The class should be serializable.

The reason being, JavaBeans were designed for Reusability where JavaBeans could travel through any Java technologies (e.g. Servlets, JSPs, RMI, Web Services, etc.).

That's my 2cent worth on why we have getters/setters. I mostly create JavaBeans.


Some people think that they should always encapsulate all fields by using setters/getters. Others think that this practice should not be used at all.

If your class does not have any logic for the fields and just is used as a holder, you can skip using methods and just declare your fields as public. This concept is also called a Data Transfer Object (or Messenger.) But as a rule you should use final attribute for such fields to make your class immutable:

public class TwoTuple<A,B> {
  public final A first;
  public final B second;
  public TwoTuple(A a, B b) { first = a; second = b; }
}

However you must/or it's strongly recommended to use setters/getters:

  • in web applications sometimes there are requirements to use setters/getters. See POJO/JavaBean objects.
  • if your class is going to be used in concurrent environment. See Java Concurrency in Practice, Section 3.2: "Whether another thread actually does something with a published reference doesn't really matter, because the risk of misuse is still present.[7] Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation: it makes it practical to analyze programs for correctness and harder to violate design constraints accidentally"
  • if you want to add some extra logic when you set/get values you must use setters/getters. Just read about encapsulation and its advantages.

My own opinion always declare fields as "private final" and only then, if needed change these properties.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜