Later on, if we want to add any extra logic while getting and setting the variable, this will impact the existing client that uses the API. So any changes to this public field will require a change to each class that refers to it. On the other hand, with accessor methods, one can easily add some logic, like caching some data or lazy initialization. Accessor methods also allow us to fire a property changed event if the new value is different from the previous value.
Another advantage of using setters to set values is that we can use the method to preserve an invariant or perform some special processing when setting values.
Fields can be declared public for package-private or private nested classes. Exposing fields in these classes produces less visual clutter compared to the accessor method approach, both in the class definition and in the client code that uses it.
If a class is package-private or is a private nested class, there is nothing inherently wrong with exposing its data fields — assuming they do an adequate job of describing the abstraction provided by the class. Such code is restricted to the package where the class is declared, while the client code is tied to a class's internal representation. We can change it without modifying any code outside that package. Moreover, in the case of a private nested class, the scope of the change is further restricted to the enclosing class.
Another example of a design that uses public fields is JavaSpace entry objects. Ken Arnold described the process they went through to decide to make those fields public instead of private with get and set methods here. Now, this sometimes makes people uncomfortable because they've been told not to have public fields and that public fields are bad.
Rules have reasons. And the reason for the private data rule doesn't apply in this particular case. 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? 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:. 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? 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.
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. 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. 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. In a pure object-oriented world getters and setters is a terrible anti-pattern. 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. You may find more about them in Section 3. There are many reasons. My favorite one is when you need to change the behavior or regulate what you can set on a variable.
For instance, lets say you had a setSpeed int speed method. But you want that you can only set a maximum speed of You would do something like:. Have fun hunting down every usage of the public field instead of just modifying your setter. For example, if foo was public, I could easily set it to null and then someone else could try to call a method on the object.
But it's not there anymore! With a setFoo method, I could ensure that foo was never set to null. Accessors and mutators also allow for encapsulation - if you aren't supposed to see the value once its set perhaps it's set in the constructor and then used by methods, but never supposed to be changed , it will never been seen by anyone.
Depends on your language. You've tagged this "object-oriented" rather than "Java", so I'd like to point out that ChssPly76's answer is language-dependent. In Python, for instance, there is no reason to use getters and setters. If you need to change the behavior, you can use a property, which wraps a getter and setter around basic attribute access. Something like this:. Thanks, that really clarified my thinking. Now here is almost 10 almost good reasons NOT to use getters and setters:.
I've done a little performance test. I wrote a class "NumberHolder" which, well, holds an Integer. You can either read that Integer by using the getter method anInstance. My programm reads the number 1,,, times, via both ways. That process is repeated five times and the time is printed. I've got the following result:. You see, the getter is almost always a bit faster. Then I tried with different numbers of cycles. Instead of 1 million, I used 10 million and 0. The results:. With 10 million cycles, the times are almost the same.
Here are thousand 0. Also with different amounts of cycles, the getter is a little bit faster than the regular way. I hope this helped you. EDIT: I answered this question because there are a bunch of people learning programming asking this, and most of the answers are very technically competent, but they're not as easy to understand if you're a newbie.
We were all newbies, so I thought I'd try my hand at a more newbie friendly answer. A very simple class that holds how much liquid is in it, and what its capacity is in milliliters. Well, you wouldn't expect that to work, right? You want there to be some kind of sanity check. And worse, what if I never specified the maximum capacity? Oh dear, we have a problem. But there's another problem too.
What if bottles were just one type of container? What if we had several containers, all with capacities and amounts of liquid filled? If we could just make an interface, we could let the rest of our program accept that interface, and bottles, jerrycans and all sorts of stuff would just work interchangably. Wouldn't that be better? Since interfaces demand methods, this is also a good thing. Now notice how much more robust this is. We can deal with any type of container in our code now by accepting LiquidContainer instead of Bottle.
And how these bottles deal with this sort of stuff can all differ. You can have bottles that write their state to disk when it changes, or bottles that save on SQL databases or GNU knows what else. And all these can have different ways to handle various whoopsies. The Bottle just checks and if it's overflowing it throws a RuntimeException.
But that might be the wrong thing to do. There is a useful discussion to be had about error handling, but I'm keeping it very simple here on purpose.
People in comments will likely point out the flaws of this simplistic approach. Please note also that you can't change the capacity of a bottle. It's now set in stone. You could do this with an int by declaring it final. But if this was a list, you could empty it, add new things to it, and so on. You can't limit the access to touching the innards. There's also the third thing that not everyone has addressed: getters and setters use method calls.
That means that they look like normal methods everywhere else does. Instead of having weird specific syntax for DTOs and stuff, you have the same thing everywhere. Even though the getter and setter methods do not add new functionality, we can change our mind come back later to make that method.
Suppose we need to store the details of this Person. This Person has the fields name , age and sex. Doing this involves creating methods for name , age and sex. Now if we need create another person, it becomes necessary to create the methods for name , age , sex all over again. Instead of doing this, we can create a bean class Person with getter and setter methods.
So tomorrow we can just create objects of this Bean class Person class whenever we need to add a new person see the figure. Thus we are reusing the fields and methods of bean class, which is much better.
In other words, the only way you can specify a field in an interface is by providing a method for writing a new value and a method for reading the current value.
Don't use getters setters unless needed for your current delivery I. Don't think too much about what would happen in the future, if any thing to be changed its a change request in most of the production applications, systems.
I would not take advantage of ignorance of business owners of deep technical know how just because I think it's correct or I like the approach. I have massive system written without getters setters only with access modifiers and some methods to validate n perform biz logic.
If you absolutely needed the. Use anything. It can be useful for lazy-loading. I can easily port to another graphical environment without changing the code, so the only problem is a little clutter. You might object by saying, "But what about JavaBeans? You can certainly build JavaBeans without getters and setters. Unfortunately, nobody did that. Accessors were created solely as a way to tag certain properties so a UI-builder program or equivalent could identify them.
You aren't supposed to call these methods yourself. They exist for an automated tool to use. This tool uses the introspection APIs in the Class class to find the methods and extrapolate the existence of certain properties from the method names. In practice, this introspection-based idiom hasn't worked out. It's made the code vastly too complicated and procedural.
Programmers who don't understand data abstraction actually call the accessors, and as a consequence, the code is less maintainable. For this reason, a metadata feature will be incorporated into Java 1. So instead of:. The UI-construction tool or equivalent will use the introspection APIs to find the properties, rather than examine method names and infer a property's existence from a name.
Therefore, no runtime accessor damages your code. First, as I discussed earlier, it's okay for a method to return an object in terms of an interface that the object implements because that interface isolates you from changes to the implementing class.
This sort of method that returns an interface reference is not really a "getter" in the sense of a method that just provides access to a field. If you change the provider's internal implementation, you just change the returned object's definition to accommodate the changes. You still protect the external code that uses the object through its interface. Here are the latest Insider stories. More Insider Sign Out. Sign In Register.
Sign Out Sign In Register. Latest Insider. Check out the latest Insider stories here. More from the IDG Network. How to use Java generics to avoid ClassCastExceptions.
Meet the new JBoss. Java Elementary language features. What is Kotlin? The Java alternative explained. It makes more sense to me. Again, the Setter function version looks neater to me. Once you get this set of intent down, code written with Getter and Setter functions will become easier to parse. A Car has fuel. When the car leaves the factory, it has 50 litres of fuel. But when you expose the fuel property this way, we allow users to make changes to fuel without limits.
If you used a Setter function for fuel , you can create a safeguard for the possible limits. If you enjoyed this article, please tell a friend about it!
Share it on Twitter.
0コメント