Why use getters and setters/accessors?

472,134

Solution 1

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.

Solution 2

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 :-)

Solution 3

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).

Solution 4

Lots of people talk about the advantages of getters and setters but I want to play devil's advocate. Right now I'm debugging a very large program where the programmers decided to make everything getters and setters. That might seem nice, but its a reverse-engineering nightmare.

Say you're looking through hundreds of lines of code and you come across this:

person.name = "Joe";

It's a beautifully simply piece of code until you realize its a setter. Now, you follow that setter and find that it also sets person.firstName, person.lastName, person.isHuman, person.hasReallyCommonFirstName, and calls person.update(), which sends a query out to the database, etc. Oh, that's where your memory leak was occurring.

Understanding a local piece of code at first glance is an important property of good readability that getters and setters tend to break. That is why I try to avoid them when I can, and minimize what they do when I use them.

Solution 5

In a pure object-oriented world getters and setters is a terrible anti-pattern. Read this article: Getters/Setters. Evil. Period. In a nutshell, they encourage programmers to think about objects as of data structures, and this type of thinking is pure procedural (like in COBOL or C). In an object-oriented language there are no data structures, but only objects that expose behavior (not attributes/properties!)

You may find more about them in Section 3.5 of Elegant Objects (my book about object-oriented programming).

Share:
472,134
Dean J
Author by

Dean J

I like working with good people, building interesting things, and pulling up others to do more. I generally lead small offices or mid-size organizations. I’m an engineer (PHP/Java/C++/Python/JS/C#/etc). I’ve driven major increases in revenue, while simultaneously improving user quality. I have experience in technical design, process improvement, team leadership, user experiments, and data analysis. I’ve interviewed hundreds of people and worked in multiple roles with hire/fire responsibilities. Extensive K-12 outreach, work as a teaching assistant, and an awful lot of patents. Prior to technology, I worked as a cab driver, concert promoter, and bartender. If there was a course that computer science degrees lack that was designed to make you a much better engineer early-career, even odds that The Pragmatic Programmer and Code Complete would be the texts. As the less-technical guide to working in the software industry, Team Geek is worth a read. (Or it's second version, Debugging Teams.) For interviews specifically, Steve Yegge made a post that got me my job, and I wrote a later article talking about technical interviews aimed at undergrads. Gayle McDowell's set of books are the full length master class. Meanwhile, some of my responses on stackoverflow: What should a developer know about UI design? Pitfalls when outsourcing? Why is a data structures course important? When should you break away from xxxx to improve performance? Why isn't the Referral Removed for HTTPS -> HTTP? Meta: in the comments, showing someone how to ask questions

Updated on March 10, 2022

Comments

  • Dean J
    Dean J over 2 years

    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.

    • Asaph
      Asaph over 14 years
      @Dean J: Duplicate with many other questions: stackoverflow.com/search?q=getters+setters
    • Tordek
      Tordek over 14 years
      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.
    • OMG Ponies
      OMG Ponies over 14 years
      Google "accessors are evil"
    • Christian Hayter
      Christian Hayter over 14 years
      "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.
    • Dave Jarvis
      Dave Jarvis over 14 years
    • OscarRyz
      OscarRyz over 14 years
      Except for 6 and 8, I would dare to say that none of those points are applied in 99% of the cases. Still I would like java use String s = employee.name() and employee.name("oscar") instead of getName() setName()
    • Dean J
      Dean J over 14 years
      @Oscar Reyes, yeah, I'd agree that 6 & 8 are the most common two from my experience. That said, I still prefer not using the C#ish syntax; my old man brain gets confused.
    • Prasanth
      Prasanth almost 12 years
      Well, I am surprised no one is talking about data synchronization. Suppose you are using public String foo; its not thread safe! Instead you can define getter setters with synchronization techniques to avoid data infidelity[i mean another thread messing up the foo]. I felt it's worth mentioning.
    • sbi
      sbi almost 12 years
      @goldenparrot: More often than never, synchronizing single accesses to an object is way to inefficient, or even prone to synchronization problems (when you need to change several properties of an object at once). IME, you often need to wrap operations as a whole that do multiple accesses to an object. That can only be accomplished by synchronization on the side of the users of a type.
    • Keith Pinson
      Keith Pinson over 11 years
      Don't compile your favorite parts of all the answers into the question itself. This is a Q&A site, not a forum.
    • Timo Huovinen
      Timo Huovinen almost 11 years
      @ErikReppen what should I read to understand OOP in the first place?
    • Timo Huovinen
      Timo Huovinen almost 11 years
      There is also the very important issue of sharing code with others, if you treat object fields as parts of the outside interface for other people to use then changing the field to a function might be impossible without breaking changes in other peoples code.
    • Timo Huovinen
      Timo Huovinen almost 11 years
      @ErikReppen Thank you for the link, I am working on understanding what OOP is supposed to be, but it is proving to be difficult with the amount of misinformation floating around. P.S. I also find wikipedia to be one of the best sources in many scientific fields.
    • Erik  Reppen
      Erik Reppen almost 11 years
      @TimoHuovinen it's all about not having to figure out which of 500 functions is actually altering a value. You make a value or set of values something's responsibility rather than something to be placed on a param/return rollercoaster. Avoid vanilla getters/setters and public properties and you'll often find yourself needing to stop and think about how to model your app in a way that is typically easier to read, modify, re-use large pieces of, debug, and have confidence in without testing the bejeezus out of it. Java and C# overfeatured OOP and then abandoned it, IMO.
    • AgilePro
      AgilePro over 9 years
      Another article attempting guidelines about where and when to use getters and setters: Public or Private Member Variables? The principle of YAGNI guides us to not add constructs until we really know we are going to need them.
    • Agi Hammerthief
      Agi Hammerthief over 9 years
      Points 2, 3 (?), 4, 5 and 8: tentative yes. The others, definite no. Why does it matter if you used Python, C#, Ruby, Objective-C or an esolang if your code's simple, elegant and easily maintainable/extendable?
    • sitilge
      sitilge almost 9 years
      666 upvotes doesn't seem to be coincidence
    • Kaiserludi
      Kaiserludi over 8 years
      "People can easily tell you didn't use Python." should actually be Nr. 1!
    • Joschua
      Joschua almost 8 years
      @Kaiserludi Could you illustrate how that's a good thing?
    • Joschua
      Joschua almost 8 years
      @DeanJ Do you mind explaining number 10?
    • Kaiserludi
      Kaiserludi almost 8 years
      @Joshua: I was just kidding, because the author clearly wasn't serious when adding that one to the list.
    • Steve Hollasch
      Steve Hollasch almost 8 years
      11. These are useful locations to set breakpoints when debugging state retrieved/modified from various locations.
    • VGR
      VGR over 7 years
      A recent question has reminded me of another reason for set-methods: the ability to trigger a property change.
  • Dean J
    Dean J over 14 years
    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.
  • ChssPly76
    ChssPly76 over 14 years
    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.
  • Vilius Surblys
    Vilius Surblys over 14 years
    Validation is a classic example of doing something special in the setter, especially if you don't fully trust the consumers of your code...
  • ChssPly76
    ChssPly76 over 14 years
    Yes, I've said as much in a comment below my answer. Java is not the only language to use getters / setters as a crutch just like Python is not the only language able to define properties. The main point, however, still remains - "property" is not the same "public field".
  • Nathan Fellman
    Nathan Fellman over 14 years
    Hunting down every usage of the public field shouldn't be that hard. Make it private and let the compiler find them.
  • LBushkin
    LBushkin over 14 years
    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.
  • Hardryv
    Hardryv over 14 years
    that's true of course, but why make it any harder than it was designed to be. The get/set approach is still the better answer.
  • UpTheCreek
    UpTheCreek over 14 years
    @LBushkin - assuming your code will not be consumed publicly.
  • steamer25
    steamer25 over 14 years
    Re: C#. If you add functionality to a get/set wouldn't that require recompilation anyway?
  • John Millikin
    John Millikin over 14 years
    @steamer25: sorry, mis-typed. I meant that clients of the class will have to be recompiled.
  • jcdyer
    jcdyer over 14 years
    @ChssPly76: but the main reason for using getters and setters is to prevent having to change the interface when you want to add more functionality, which means that it's perfectly acceptable--idiomatic even--to use public fields until such functionality is needed.
  • ChssPly76
    ChssPly76 over 14 years
    @jcd - not at all. You're defining your "interface" (public API would be a better term here) by exposing your public fields. Once that's done, there's no going back. Properties are NOT fields because they provide you with a mechanism to intercept attempts to access fields (by routing them to methods if those are defined); that is, however, nothing more than syntax sugar over getter / setter methods. It's extremely convenient but it doesn't alter the underlying paradigm - exposing fields with no control over access to them violates the principle of encapsulation.
  • jcdyer
    jcdyer over 14 years
    @ChssPly76—I disagree. I have just as much control as if they were properties, because I can make them properties whenever I need to. There is no difference between a property that uses boilerplate getters and setters, and a raw attribute, except that the raw attribute is faster, because it utilizes the underlying language, rather than calling methods. Functionally, they are identical. The only way encapsulation could be violated is if you think parentheses (obj.set_attr('foo')) are inherently superior to equals signs (obj.attr = 'foo'). Public access is public access.
  • Dean J
    Dean J over 14 years
    Okay, second question; in the case where it's a project where you're not exporting source to anyone, and you have full control of the source... are you gaining anything with getters and setters?
  • matbrgz
    matbrgz over 14 years
    In any non-trivial Java project you need to code to interfaces in order to make things manageable and testable (think mockups and proxy objects). If you use interfaces you need getters and setters.
  • cmcginty
    cmcginty about 12 years
    sounds like pre-mature optimization
  • sbi
    sbi almost 12 years
    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
    sbi almost 12 years
    The encapsulation getters and setters offer are laughably thin. See here.
  • sbi
    sbi almost 12 years
    I think the crucial argument is that, "if you were designing an interface and weren't sure whether direct access to something was OK, then you should have kept designing." That is the most important problem with getters/setters: They reduce a class to a mere container of (more or less) public fields. In real OOP, however, an object is more than a container of data fields. It encapsulates state and algorithms to manipulate that state. What's crucial about this statement is that the state is supposed to be encapsulated and only to be manipulated by the algorithms provided by the object.
  • R. Martinho Fernandes
    R. Martinho Fernandes almost 12 years
    "What I did above is override the existing methods on the super class with my new functionality." With functionality that we all hope was already properly documented for the old interface, right? Otherwise you just violated the LSP and introduced a silent breaking change that would have been caught by the compiler if there were no getters/setters in sight.
  • R. Martinho Fernandes
    R. Martinho Fernandes almost 12 years
    I suppose that changing the behaviour of the getter or setter isn't a breaking change then. </sarcasm>
  • R. Martinho Fernandes
    R. Martinho Fernandes almost 12 years
    Adding validation logic to a setFoo method will not require changing the interface of a class at the language level, but it does change the actual interface, aka contract, because it changes the preconditions. Why would one want the compiler to not treat that as a breaking change when it is?
  • thecoshman
    thecoshman about 11 years
    If your public interface states that 'foo' is of type 'T' and can be set to anything, you can never change that. You can not latter decide to make it of type 'Y', nor can you impose rules such as size constraints. Thus if you have public get/set that do nothing much set/get, you are gaining nothing that a public field will not offer and making it more cumbersome to use. If you have a constraint, such as the object can be set to null, or the value has to be within a range, then yes, a public set method would be required, but you still present a contract from setting this value that can't change
  • Erik  Reppen
    Erik Reppen about 11 years
    That problem is not an indicator that you needed to use set or get methods. It's an indicator that the entire team needs to have the IDEs slapped out of their hands and taught to write and understand and maintain OOP without one.
  • ChssPly76
    ChssPly76 about 11 years
    @ErikReppen As I've commented above, this depends on a particular language implementation. For the ones where properties are not first-class citizens (like Java) it's completely irrelevant whether you're using some IDE or plain vi to write your code - once property has been exposed directly you cannot take it back.
  • Erik  Reppen
    Erik Reppen about 11 years
    @ChssPly76 IMO, you really shouldn't be exposing properties directly or indirectly in the first place (most of the time - always exceptions to a rule). They are that object's responsibility. When you design in terms of data only changing as a side-effect of objects telling each other to do things other than what data to set, you have to stop and think occasionally but it leads to much more maintainable/modular architecture IMO. It's what makes it possible to maintain complexity in a dynamic language.
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 11 years
    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.
  • Timo Huovinen
    Timo Huovinen almost 11 years
    @jcdyer as much control yes, but not as much readability, others often wrongly assume that obj.attr = 'foo' just sets the variable without anything else happening
  • Erik  Reppen
    Erik Reppen almost 11 years
    @ChssPly76 I didn't explain the point of removing the IDEs. Try writing code without one when you've effectively globally accessed the same var from 238 places and now have to figure out where something went wrong.
  • Phil
    Phil over 10 years
    This is argument against syntactic sugar, not against setters in general.
  • Phil
    Phil over 10 years
    @R.MartinhoFernandes doesn't always have to be. TBYS
  • Phil
    Phil over 10 years
    It would be implemented at runtime with "trivial methods". Actually, probably non-trivial.
  • Phil
    Phil over 10 years
    @R.MartinhoFernandes "... and then run hibernate tools to generate the java code" this isn't a case of changing the behavior of some class, this is a work around to a shitty tool. Perhaps the contract (which in this case is in the subclass) always was for that "surprise". Could be an argument for has-a instead of is-a though.
  • Phil
    Phil over 10 years
    @R.MartinhoFernandes how does one fix this "broken" problem? The compiler can't tell if it's breaking or not. This is only a concern when you are writing libraries for others, but you're making it out as universal zOMG here be dragons!
  • Phil
    Phil over 10 years
    Why can't a contract change?
  • Phil
    Phil over 10 years
    Why all the talk about removing the IDE? Why would anyone do that? Sure, I know how to use ed, and at times, it's the tool for the job. Writing software, however, isn't one of those times.
  • R. Martinho Fernandes
    R. Martinho Fernandes over 10 years
    Requiring recompilation, as mentioned in the answer, is one way the compiler can make you aware of a possible breaking change. And almost everything I write is effectively "a library for others", because I don't work alone. I write code that has interfaces that other people in the project will use. What's the difference? Hell, even if I will be the user of those interfaces, why should I hold my code to lower quality standards? I don't like working with troublesome interfaces, even if I'm the one writing them.
  • R. Martinho Fernandes
    R. Martinho Fernandes over 10 years
    Why should things keep on compiling if contracts change?
  • R. Martinho Fernandes
    R. Martinho Fernandes over 10 years
    @GraemePerrow having to change them all is an advantage, not a problem :( What if you had code that assumed speed could be higher than 100 (because, you know, before you broke the contract, it could!) (while(speed < 200) { do_something(); accelerate(); })
  • Darrell Teague
    Darrell Teague over 10 years
    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.
  • icc97
    icc97 almost 10 years
    So then does the getter call the setter?
  • quillbreaker
    quillbreaker almost 10 years
    I've added a code sample of how I've done it in the past - essentially, you store the actual class in a protected member, then return that protected member in the get accessor, initializing it if it is not initialized.
  • Zorf
    Zorf over 9 years
    @sbi I don't see why? I mean, if you have a very basic case of a "person" class, a field is going to be first_name and obviously you want to just get that field verbatim at one point. And you should use a getter. For mayhap in the future you will completely change the implementation of your class such that the class asyncroneously retrieves this from a server or does whatever else.
  • sbi
    sbi over 9 years
    @Zorf: If all your person does it to store first and last name, then it's nothing but a (glorified) struct and, thus, not OOP, but Structured Programming. (Whether setters and getters gain you anything in this scenario over plainly accessing the data is dubious at best: A) How else but in a string would you represent a person's names? And I'm talking practical scenarios here, not theory, because B) in 20 years of practice I have never run into such a situation.)
  • ely
    ely over 9 years
    @TimoHuovinen How is that any different than a user in Java assuming that obj.setAttr('foo') "just sets the variable without anything else happening"? If it's a public methods, then it's a public method. If you use it to achieve some side-effect, and it is public, then you had better be able to count on everything working as if only that intended side effect happened (with all other implementation details and other side effects, resource use, whatever, hidden from the user's concerns). This is absolutely no different with Python. Python's syntax to achieve the effect is just simpler.
  • AgilePro
    AgilePro over 9 years
    You did not answer the question which was: "What's the advantage of using getters and setters - that only get and set ..." Your example is not this case, and therefor you answer does not apply to this question.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    A clear example of this is when setting one attribute's value affects one or more other attribute values. Trivial example: Say you store the radius of a circle Using circ.set_radius()` doesn't really achieve anything setting radius directly through circ.radius doesn't. However, get_diameter(), get_circumference() and get_area() can perform calculations based on radius. Without getters, you have to perform the calculations yourself and check that you've got them right.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    "... a well-defined interface that you can't just screw with the internals of" and validation in setters.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    I fail to see what you achieve by not using the superclass' properties directly.
  • Haakon Løtveit
    Haakon Løtveit over 8 years
    In Java you don't have getters and setters like that. What you do have is Project Lombok which uses annotations to much the same effect. So if you want this niceness but in Java and not C#, then you know where to go. :)
  • Piotr Aleksander Chmielowski
    Piotr Aleksander Chmielowski over 8 years
    It is a VERY bad example! Someone should call: myCar.setSpeed(157); and after few lines speed = myCar.getSpeed(); And now... I wish you happy debugging while trying to understand why speed==100 when it should be 157
  • Stephen C
    Stephen C almost 8 years
    Interesting viewpoint. But in most programming contexts what we need is data structures. Taking the linked article's "Dog" example. Yes, you can't change a real-world dog's weight by setting an attribute ... but a new Dog() is not a dog. It is object that holds information about a dog. And for that usage, it is natural to be able to correct an incorrectly recorded weight.
  • Stephen C
    Stephen C almost 8 years
    Well, I put it to you that most useful programs don't need to model / simulate real world objects. IMO, this is not really about programming languages at all. It is about what we write programs for.
  • Hubert Grzeskowiak
    Hubert Grzeskowiak almost 8 years
    I'd never expect a getter or setter to be an expensive operation. In such cases better use a factory: use all setters you need and then invoke the expensive execute or build method.
  • Hubert Grzeskowiak
    Hubert Grzeskowiak almost 8 years
    I think the semantics of the given code samples are totally different. The first sample also creates a circular reference: mesh.boundingVolume.mesh == mesh
  • Hubert Grzeskowiak
    Hubert Grzeskowiak almost 8 years
    Please note that the question was asked without a specific language in mind.
  • Alex
    Alex almost 8 years
    There's a "noticable" overhead having a function call to access the memory instead of simply loading an object's address and adding an offset to access the members. Chances are the VM flat-optimized your getter anyway. Regardless, the mentioned overhead isn't worth losing all the benefits of getters/setters.
  • FacelessTiger
    FacelessTiger over 7 years
    To me having tons of getters and setters that do nothing unique is useless. getFullName is a exception because it does something else. Having just the three variables public then keeping getFullName will make the program easier to read but still have that fullname thing hidden. Generally I'm completely fine with getters and setters if a. they do something unique and/or b. you only have one, yeah you could have a public final and all that but nah
  • Bill K
    Bill K about 7 years
    Real world or not, yegor is completely right. If what you have is truly a "Struct" and you don't need to write any code that references it by name, put it in a hashtable or other data structure. If you do need to write code for it then put it as a member of a class and put the code that manipulates that variable in the same class and omit the setter & getter. PS. although I mostly share yegor's viewpoint, I have come to believe that annotated beans without code are somewhat useful data structures--also getters are sometimes necessary, setters shouldn't ever exist.
  • Bill K
    Bill K about 7 years
    your getBalance/setBalance aren't getter/setter if they have other code, are they? Also why expose balance? Wouldn't it be safer to have an applyPayment or applyDebt that allowed balance checking and maybe a memo field to say where the payment was from? Hey! I just improved your design AND removed the setter and getter. That's the thing about setters/getters, it pretty much always improves your code to remove them, not that they are "Wrong", just that they nearly always lead to worse code. Properties (as in C#), by the way, have exactly the same issue.
  • Bill K
    Bill K about 7 years
    I got carried away--this entire answer, although correct and relevant, doesn't address the question directly. Perhaps it should say "Both setters/getters AND public variables are wrong"... To be absolutely specific, Setters and writable public variables should never ever be used whereas getters are pretty much the same as public final variables and are occasionally a necessary evil but neither is much better than the other.
  • C Perkins
    C Perkins about 7 years
    Perhaps method names sometimes reflect a developer's deeper understanding, and maybe it does go the other way...that language elements influence a developers habits. But language syntax and symbols are rife with elements that have evolved over time and are no longer (if ever) an accurate metaphor for what they are supposed to represent. Although you make some good points, it feels to me like arguing that Java is a stupid programming language name because we can't really drink it sitting in a cafe. It's okay to redefine "set" with a more complete meaning without actually doing away with it.
  • meguli
    meguli about 7 years
    I have never understood getters/setters. From the first Java101 class I took at the college, they seemed like they encourage building lacking abstractions and confused me. But there is this case then: your object may possibly have so many different behavior. Then it is possible that you might not hope to implement them all. You make setters/getters and conveniently tell your users that if you need a behavior that I missed, inherit and implement them yourself. I gave you accessors after all.
  • Andrew Hows
    Andrew Hows over 6 years
    The benefit with this is that you can change the internals of the class, without changing the interface. Say, instead of three properties, you had one - an array of strings. If you've been using getters and setters, you can make that change, and then update the getter/setters to know that names[0] is first name, names[1] is middle, etc. But if you just used public properties, you would also have to change every class accessed Employee, because the firstName property they've been using no longer exists.
  • Sara M
    Sara M over 6 years
  • matbrgz
    matbrgz over 6 years
    Today this can be done with an annotation preprocessor.
  • Matthias Ronge
    Matthias Ronge about 6 years
    In this sense of “alive objects”, there should be no set…() and get…(), but rather remember…() and tell…(). Just that get and set is shorter to type. Also, an object describing another object—like a paper-bound form—should include that in the class name, but that again is lengthy. We cannot change the weight of the dog, and we don’t do, what we change is the weight noted down on the dog admission form.
  • Basil Bourque
    Basil Bourque almost 6 years
    Objective-C uses annotations to mark properties. If the programmer of the class provides no accessor (getter/setter) methods for the annotated member variable, such methods are automatically synthesized. The authoring programmer can always go back and provide an implementation of the accessor anytime she desires. I have no idea why Java has not adopted such a simple solution to lacking properties.
  • Heetola
    Heetola about 4 years
    @AndrewHows from what I've seen in real life, when people change the internals of the class they also change the interface and do a big refactoring of all the code
  • Heetola
    Heetola about 4 years
    you can do right clic> find usage on a member exactly like on a getter/setter
  • Heetola
    Heetola about 4 years
    We are the develloper, a lack of setter/getter does not protect anything we can just add them....
  • andreagalle
    andreagalle almost 3 years
    concerning the last point: why, for example, the set could be protected?
  • carloswm85
    carloswm85 over 2 years
    This is an excellent overview. Adding a comprehensive example would make it terrific.
  • 0xff
    0xff over 2 years
    @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.
  • Eugene
    Eugene over 2 years
    -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.
  • Zbyszek
    Zbyszek about 2 years
    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.
  • tedtanner
    tedtanner about 2 years
    @Phil I’d disagree. One can just as easily write a public void setName(String name) (in Java) that does the same exact things. Or worse, a public void setFirstName(String name) that does all those things.
  • Phil
    Phil about 2 years
    @tedtanner and when you do, it's no longer a mystery that a method is being invoked, since it's not disguised as field access.
  • tedtanner
    tedtanner about 2 years
    @Phil I am with you on that one. I don't believe in hiding method calls. I just want to point out that Kai's argument is less about syntactic sugar and more about how setters (including ones that look like method calls) shouldn't have side effects like changing other data members in the object or querying the database.
  • Phil
    Phil about 2 years
    @tedtanner I think we share opinions as to what setters and getters should do, and as to whether they should be hidden like this or not, but the fact is when they are hidden, it's always syntactic sugar - it's always a method call, on the machine. Back in 2009 when the answer was written, and in 2013 when I wrote my comment, one used annotations and either codegen or pointcut type solutions to do this, and it was all very non-standard. Today in 2022, I haven't touched Java for years 😂