Categories
abstraction getter java oop setter

Why use getters and setters/accessors?

1777

What’s the advantage of using getters and setters – that only get and set – instead of simply using public fields for those variables?

If getters and setters are ever doing more than just the simple get/set, I can figure this one out very quickly, but I’m not 100% clear on how:

public String foo;

is any worse than:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

Whereas the former takes a lot less boilerplate code.

23

  • 8

    @Dean J: Duplicate with many other questions: stackoverflow.com/search?q=getters+setters

    – Asaph

    Oct 14, 2009 at 18:26

  • 9

    Of course, both are equally bad when the object doesn’t need a property to be changed. I’d rather make everything private, and then add getters if useful, and setters if needed.

    – Tordek

    Oct 14, 2009 at 18:29

  • 31

    Google “accessors are evil”

    Oct 14, 2009 at 18:45

  • 39

    “Accessors are evil” if you happen to be writing functional code or immutable objects. If you happen to be writing stateful mutable objects, then they are pretty essential.

    Oct 14, 2009 at 19:10

  • 22

    Tell, don’t ask. pragprog.com/articles/tell-dont-ask

    Oct 14, 2009 at 22:18

1161

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class – beyond just the argument of encapsulation and making future changes easier.

Here are the some of the reasons I am aware of:

  • Encapsulation of behavior associated with getting or setting the property – this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change – allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property – particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime – debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/setters – Mocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels – for example the get may be public, but the set could be protected.

5

  • concerning the last point: why, for example, the set could be protected?

    Sep 3, 2021 at 8:15


  • This is an excellent overview. Adding a comprehensive example would make it terrific.

    Oct 8, 2021 at 22:19

  • 1

    @andreagalle There’s many reason that could be the case. Maybe you have an attribute that is not to be changed from the outside. In that scenario you could also completely remove the setter. But maybe you want to change this change-blocking behaviour in a subclass, which could then utilize the protected method.

    – 0xff

    Nov 1, 2021 at 18:22

  • 3

    -1 Because point no. 1 is the dev trap #1: Classical Getters / Setters do not encapsulate behaviour. Because they do not express behaviour. Cutomer::setContractEndDate() / Customer::getContractEndDate() is no behaviour and it does not encapsulate anything at all. It’s faking encapsulation. Customer::cancelContract() is a behaviour and that’s where you actually can modify the logic without changing the interface. It won’t work if you make atomic properties public through getters and setters.

    – Eugene

    Feb 13 at 1:24


  • There’re many good reasons to walk outside in kevlar riot suit, gas mask and shield. You’ll be safer! You’ll be protected from chemical and biological threats. And many more! So every approach that consider only positives or only negatives is unbalanced so in practice lead to looses. Because you have to pay, for the “good thing” and the price is not smth you can neglect. What is the price of getters and setters? Your time, your attention, your life in effect. So use them whenever you and others derive more benefits in categories of time spent on creating and maintaining code.

    – Zbyszek

    Apr 9 at 5:35

606

Because 2 weeks (months, years) from now when you realize that your setter needs to do more than just set the value, you’ll also realize that the property has been used directly in 238 other classes 🙂

15

  • 114

    I’m sitting and staring at a 500k line app where it’s never been needed. That said, if it’s needed once, it’d start causing a maintenance nightmare. Good enough for a checkmark for me.

    – Dean J

    Oct 14, 2009 at 18:24


  • 22

    I can only envy you and your app 🙂 That said, it really depends on your software stack as well. Delphi, for example (and C# – I think?) allows you to define properties as 1st class citizens where they can read / write a field directly initially but – should you need it – do so via getter / setter methods as well. Mucho convenient. Java, alas, does not – not to mention the javabeans standard which forces you to use getters / setters as well.

    – ChssPly76

    Oct 14, 2009 at 18:27

  • 20

    While this is indeed a good reason for using accessors, many programming environments and editors now offer support for refactoring (either in the IDE or as free add-ins) which somewhat reduces the impact of the problem.

    – LBushkin

    Oct 14, 2009 at 18:59

  • 86

    sounds like pre-mature optimization

    – cmcginty

    Jun 15, 2012 at 21:31


  • 46

    The question you need to ask when you wonder whether to implement getters and setters is: Why would users of a class need to access the class’ innards at all? It doesn’t really matter whether they do it directly or shielded by a thin pseudo layer — if users need to access implementation details, then that’s a sign that the class doesn’t offer enough of an abstraction. See also this comment.

    – sbi

    Aug 23, 2012 at 21:13

422

A public field is not worse than a getter/setter pair that does nothing except returning the field and assigning to it. First, it’s clear that (in most languages) there is no functional difference. Any difference must be in other factors, like maintainability or readability.

An oft-mentioned advantage of getter/setter pairs, isn’t. There’s this claim that you can change the implementation and your clients don’t have to be recompiled. Supposedly, setters let you add functionality like validation later on and your clients don’t even need to know about it. However, adding validation to a setter is a change to its preconditions, a violation of the previous contract, which was, quite simply, “you can put anything in here, and you can get that same thing later from the getter”.

So, now that you broke the contract, changing every file in the codebase is something you should want to do, not avoid. If you avoid it you’re making the assumption that all the code assumed the contract for those methods was different.

If that should not have been the contract, then the interface was allowing clients to put the object in invalid states. That’s the exact opposite of encapsulation If that field could not really be set to anything from the start, why wasn’t the validation there from the start?

This same argument applies to other supposed advantages of these pass-through getter/setter pairs: if you later decide to change the value being set, you’re breaking the contract. If you override the default functionality in a derived class, in a way beyond a few harmless modifications (like logging or other non-observable behaviour), you’re breaking the contract of the base class. That is a violation of the Liskov Substitutability Principle, which is seen as one of the tenets of OO.

If a class has these dumb getters and setters for every field, then it is a class that has no invariants whatsoever, no contract. Is that really object-oriented design? If all the class has is those getters and setters, it’s just a dumb data holder, and dumb data holders should look like dumb data holders:

class Foo {
public:
    int DaysLeft;
    int ContestantNumber;
};

Adding pass-through getter/setter pairs to such a class adds no value. Other classes should provide meaningful operations, not just operations that fields already provide. That’s how you can define and maintain useful invariants.

Client: “What can I do with an object of this class?”
Designer: “You can read and write several variables.”
Client: “Oh… cool, I guess?”

There are reasons to use getters and setters, but if those reasons don’t exist, making getter/setter pairs in the name of false encapsulation gods is not a good thing. Valid reasons to make getters or setters include the things often mentioned as the potential changes you can make later, like validation or different internal representations. Or maybe the value should be readable by clients but not writable (for example, reading the size of a dictionary), so a simple getter is a nice choice. But those reasons should be there when you make the choice, and not just as a potential thing you may want later. This is an instance of YAGNI (You Ain’t Gonna Need It).

2

  • 19

    Great answer (+1). My only criticism is that it took me several reads to figure out how “validation” in the final paragraph differed from “validation” in the first few (which you threw out in the latter case but promoted in the former); adjusting the wording might help in that regard.

    Jul 6, 2013 at 21:12

  • 15

    This is a great answer but alas the current era has forgotten what “information hiding” is or what it is for. They never read about immutability and in their quest for most-agile, never drew that state-transition-diagram that defined what the legal states of an object were and thus what were not.

    Nov 6, 2013 at 14:58