Dr. Axel Rauschmayer is a freelance software engineer, blogger and educator, located in Munich, Germany. Axel is a DZone MVB and is not an employee of DZone and has posted 246 posts at DZone. You can read more from them at their website. View Full User Profile

Why We Are Actually Writing Getters and Setters in Java

08.03.2010
| 21853 views |
  • submit to reddit

I often hear the opinion that writing getters and setters has something to do with better encapsulation, that using “naked” fields is bad practice. To find out if this is true, we have to look at Java history. In the mid-nineties, Sun developed the Java Bean Specification as a component model for Java. This model was supposed to help with tool support for Java, e.g. when connecting a graphical user interface with domain objects. In this case, it is useful if one can observe changes made to fields and react to them (e.g. by updating the text displayed in a window). Alas, while there are some languages that allow this kind of meta-control (Python and Common Lisp come to mind), Java does not. Thus, Java Beans introduced standardized naming that allowed one to implement a field as a pair of methods which then would manually implement the observation.

I usually code as follows: If I need just a field, I use a public field (no getters and setters), because it helps me to get started quickly and introduces less clutter. If I later change my mind, I let Eclipse introduce the indirection of the getter and setter. That means that there is no penalty for such a change and no need to think ahead! Granted, having both public fields and getters/setters affects uniformity, but the added agility is worth it for me.

Obviously, it would be nice if Java had true observable (and optionally computable) fields. This feature was initially on the table for Java 7, but did not make the cut. Maybe IDEs could help by displaying getters and setters as if they were fields. Their source code would be hidden, with visual clues indicating if such a pseudo-field is read-only etc. Additionally, auto-expansion would be improved, because pseudo-getters (such as Collection.size()), getters/setters, and fields would all be part of the same category. No more typing “.get” and hoping that the information that you are looking for is available as a properly named getter. The same kind of grouping should also be made in JavaDoc. Lastly, one could display foo.setValue("abc") as foo.value = "abc". But I’m not sure if that makes sense. 

From http://2ality.blogspot.com/2010/08/why-we-are-actually-writing-getters-and.html

Published at DZone with permission of Axel Rauschmayer, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Alessandro Santini replied on Tue, 2010/08/03 - 2:14am

I entirely agree with your thoughts - getters and setters should be used only where necessary.

I am not an AOP expert, but I imagine that bytecode enhancement could help in observing changes to a public field.

Roger Parkinson replied on Tue, 2010/08/03 - 2:30am

There are beans and beans.

I prefer to define my persistent beans with an XSD and generate them with JAXB.

That gives me getters and setters plus various other stuff I rely on like standard annotations and some intercept code. I like using AOP to intercept method calls as well. So I prefer to have this stuff all set up beforehand and it also ensures my beans don't get any custom code slipped in that has to be maintained.

But for Spring beans I just write 'em, probably in much the same way you do. They do need setters and getter, though. Plain objects I treat the same as Spring beans. I make the fields private and put setters and getters on them. That gives me somewhere I can set a break point to catch where the value is modified. I feel it gives me a level of protection from other code hacking my objects, but I'm probably being old fashioned there.

Good cross reference tools in Eclipse and other IDEs do make it easy to track down references to a field, so it isn't like it is hard to find what updates it and reads it anymore.

Howard Lovatt replied on Tue, 2010/08/03 - 2:57am

I have come across problems with fields, one example was a Complex number class:

  public class Complex {
    public double re, im;
    ...
  }

Trouble was that it turned out that we were better representing the complex numbers as magnitude and angle (because we were primarily multiplying and dividing them). We couldn't change because we didn't have control over all the source code. If we had used getters and setters we could have written:

  public class Complex {
    private double mag, arg;
    public double getRe() { ... }
    public void setRe( final double re ) { ... }
    public double getMag() { return mag; }
    public void setMag( final double mag ) { if ( mag < 0 ) { ... }; this.mag = mag; }
    ...
  }

Note the suggested solution of leaving the original fields in place wouldn't have worked for us; since we wanted to represent the data in a different way, not present the data in a different way.

Java Guy replied on Tue, 2010/08/03 - 3:06am

Why are you writing getters / setters? Most decent IDE's will generate them for you now...I know eclipse + IntelliJ do. Can't say for Netbeans as I'm not a user of it. What I usually do is: - write my fields - generate getters / setters - collapse the getter / setter methods in editor(IntelliJ my preferred)

Karl Peterbauer replied on Tue, 2010/08/03 - 3:08am

You're talking about trivial setters and getters commonly found in dumb data objects (for which I also would appreciate some syntactic sugar). However, JavaBeans setters in their original sense are typically highly complex operations involving firing property change events, attaching and detaching listeners, or invalidating certain UI parts for re-rendering in the next UI update cycle. Built-in language support for observing property changes (including support for vetoable property changes) is all but trivial.

And you should also keep your fellow coders in mind. Maybe they want to monitor your public field in their debugger, which is accomplished most easily by setting breakpoints to accessor methods ;-)

Oliver Weiler replied on Tue, 2010/08/03 - 4:36am

I actually do the opposite: I start with private. then lower the access restrictions as needed. The problem with public fields: If you publish an API with public fields, you'll never be able to make changes to the fields without breaking client code. On the other hand, if all your fields are private, you can make them package-private/protected without breaking client code.

 I'd say there is NEVER EVER a need to make a field public.

 

Eric Giese replied on Tue, 2010/08/03 - 4:45am

The concept of "fields" is in fact a design failure of java, just like the primitives.

Java separates between data fields and methods and even gives them different name scopes, so that you can have a String "name" field and String name() method. The only difference between them is that you invoke the method with "name()" instead of "name". Maybe the language designers liked Brackets...

Other languages, like Scala, simply define that there are no syntatical differences in the way in which fields and methods are invoked, so that problem ceases to exist without writing getters and setters all the time.

Back to java:
In general, i would always create "getters". I would write "xxx()" instead of "getXXX()", but thats just a personal preference. Public fields are never an alternative, because of the design problems which might not lurk up until later (except for private inner classes). Just let your IDE generate the code weight and be happy. :-)

"setters" are a burden I try to stay clear of, because mutable objects simply carry to much problems on their own. I would always start with final fields and add the mutators only later when I really need them.

Lukas Grijander replied on Tue, 2010/08/03 - 5:44am

Mi favourite syntax for fields is that of Eiffel. You can have a field at first and change it later to a getter and/or setter without needing to change client code. Maybe some future version of Java could implement some mechanism that allowed something like this. I would be very glad. In the meantime I am a getter/setter guy, mostly because I use Spring a lot. Regards

Doug Barnum replied on Tue, 2010/08/03 - 8:28am

Just to throw in my two cents. I never make a field public and always use getters/setters. When I'm writing the class I will have some idea if the property is read-only or read-write or private. I will default to private.

People may think it's weird that I use getters/setters for even private properties. I think it makes the internal code to the class more self documenting. I don't like using a private variable "directly" in many different methods. Invariably there will be a point where I'll say what the $@# type of variable is this?

double apples = getAppleCount();

is better than having "appleCount" all over the place.

By using the getters/setters the declaration of that variable is only a few lines of code away. I hate scrolling or paging to the section of the class where I declare all the class variables just to check this property. Like did I make it a Double or an Integer? I'm concentrating on a small section of code to figure something out and it's annoying to be taken away from that moment.

I also believe that this makes the job of other people who are trying to digest your code a little easier. They also don't find themselves scrolling all over the place to figure out a variable's data type if it is not obvious. It allows them to more easily figure out the code on a per method basis instead of a per class basis.

Guido Amabili replied on Tue, 2010/08/03 - 9:21am

I usually start with private fields if I do not have a complete analysis (UML Diagrams) of a given domain for the same reasons as the previous posters.

But I know coders who just need a kind of java "struct"  and who implement classes with public fields.

 

Alexandru Repede replied on Tue, 2010/08/03 - 9:36am

What about Encapsulation (a language construct that facilitates the bundling of data with the methods operating on that data; definition from Wikipedia) and Information Hidding ?

Encapsulation is supposed to be the basic block of OOP, so why break it by exposing the internal state of objects ? Why make fields public or even create getters ?

Getters are evil, some say. Read this

Why not use the alternative, "Tell don't ask"? Read this

 

Instead of asking for the internal state of objects so that you can do things with it (in other objects), you should tell your objects to do their own stuff, cause they have the data.

And if you are going to say "No way in hell I'm writing UI code together with my business", then I'm going to tell you "Create objects that represent the contract between the two concerns, put your data in them, and pass them to the UI layer/UI part of your project".

If breaking MVC Pattern is your concern, then create a "contract" between the business and UI, or other parts (ie. the Model). 

"Tell don't ask" lets you return objects as long as they have an interface (that interface is the contract between Business and UI)

 

John J. Franey replied on Tue, 2010/08/03 - 9:57am

15 years ago, while programming C++, I struggled with this same question: why getters/setters? The answer I got from the experts at the time: in order to preserve encapsulation. However, I never did have a strong leaning one way or the other. Javabean specification tipped me toward ALWAYS creating getter/setter: there are tools that can be leveraged when adhering to this spec; and IDE code generation drove the point home.

Developer Dude replied on Tue, 2010/08/03 - 10:17am

It depends on how you are using the class/interface.

If I am creating a simple tuple class that will only ever hold some values together to be passed around (rather than passing half a dozen separate args), I may make the fields public final static and assign them in the constructor, rather than creating getters/setters. Simple and safe.

If I anticipated that the field may be initialized some different way in a subclass and I anticipate the class being subclassed, then I do use getters/setters. Ditto if I am doing some checking of the field for validity, or using it to init other private fields, or to make decisions, or lazy instantiation. IMO, there are a number of good reasons to use getters/setters and IMO less good reasons to not use them.

I kind of like how Properties work in .NET

" If I later change my mind, I let Eclipse introduce the indirection of the getter and setter. That means that there is no penalty for such a change and no need to think ahead! Granted, having both public fields and getters/setters affects uniformity, but the added agility is worth it for me."

Uhhhh - no. Other people use my classes/interfaces. When I change the interface then that change ripples through their uses. Always think ahead - in the long run it does save time and effort.

replied on Tue, 2010/08/03 - 12:37pm

1. A read-only field, simply supply the getter with no public setter.

2. Custom code within your setter, which can be made final. (Which might also call an abstract public setter.) This in addition to property change listeners (which is a design flaw, if you ask me).

3. JavaBean spec and other reasons.

BUT, having said that, the IDE should  hide (not just fold, which is in itself a pain) all the accesors until told otherwise (via a view.) I think that Oracle's JDev can do that.

 

Greg Matoga replied on Tue, 2010/08/03 - 2:22pm

If you are open to some annotation processing tools I'd recommend to take a look at project Lombok. It really has useful features. It takes the duty of writing a lot boilerplate on itself and requires only to specify certain annotations.

The project looks very lively. Authors have rather ambitious plans about future improvements, but it seems they're realistic.

One thing I'd liked to see in it is the bounded property generator. At the moment, authors are working mostly on polishing API. So I decided to give it a try myself, and started this project: LomProp.

The following bean:


@BindableData
public class Bean {

    private String name;
    private int age;
}

Will be transformed into fully functional (bindable) JaveBean object! It'll have all setters, getters and will fire PropertyChangeEvents. I believe using annotation processing is a right way to tackle this sort of problems.

Nicolas Bousquet replied on Tue, 2010/08/03 - 3:58pm

Real solution is to add support to properties like in C# :

- x.y = z is clearer for me than x.setY(z).

- if needed you can latter add custom code to the getter or setter of the property.

 The point here is that the most common use case of getter/setter is just plain access to fieds. Sometime you have a getter just computing the value (or even making a copy to ensure you can't alter object internal state). But basicaly, if your getter/setter a day begin to do some real thing, then keeping the getter/setter is likely to be a wrong choice for you API. Even if documented, people using your API will not be aware of it and it will introduce some bugs, maybe even concurrency problems (in case of event propagation)...

And maybe you'll have to drop the getter and change the contract the class provide anyway.

From my experience, 99% of the time, getter/setter do nothing. Getters/Setter are accidental complexity. So that IDE have to generate them and fold them. So you have to be aware of them. So you have to use them in your code anyway (instead of just = operator). We are all used to this accidental complexity, but it's not a good thing. The fact is even if you dont need getter/setter 100% sure, if you don't put them, many will look at you like you a bad developper. It's hard to justify not putting getter/setter. In fact most of us do add them without even thinking about it. It's just a bad habbits we have. And Jave 7 could help us a lot by introducing properties.

cowwoc replied on Tue, 2010/08/03 - 10:59pm

Alexandru Repede is right. Getters and Setters aren't appropriate 85% of the time. "Tell don't ask" is the way to go.

Alessandro Santini replied on Wed, 2010/08/04 - 1:31am in response to: Nicolas Bousquet

Totally agreed.

Ignacio Coloma replied on Wed, 2010/08/04 - 2:29am

Say you have a hierarchy of classes, C extends B, B extends A. Put an attribute in B. If you later move that attribute to A (even if it's the same attribute), you will have to recompile C. This doesn't happen with getters and setters, which is a major concern for library designers (source: the Practical API Design book).

Eric Giese replied on Wed, 2010/08/04 - 5:45am

"Tell don't ask" is nice and in the spirit of oo, but it has problems on its own:

One of the main concepts of good design should be to separate data and logic, so that equivalent logic can be applied on as much similar problem cases as possible. However, static typesystems as in OO do not provide this "generality" because of the limitations which come with (single) inheritance. If you implement logic into data class which works on its own fields, its effectively "locked in", and hard to reuse anywhere else.

In OO, generality is best achieved by defining a class (or an interface) which serves as an (immutable) data container and another class which knows how to operate on this class (a handler), asking the data container for its information. Its still in the spirit of OO, but know you are not limited by the typesystem anymore, as data and logic have been decoupled.

Mladen Girazovski replied on Wed, 2010/08/04 - 6:42am

One of the main concepts of good design should be to separate data and logic, 

Actually, OOD is about the opposite: Put logic and data together if they belong together, seperating logic from data is what is done in procedural programming.

Apart from that, imho the article & discussion is mixing up several concepts, namely the "uniform access principle", encapsulation and information hiding, and the idea that the access to fields inside the class/inheritance hierachy could be encapsulated by methods.

Of course, many frameworks force you to use the JavaBean standard of getters and setters.

Eric Giese replied on Wed, 2010/08/04 - 7:52am in response to: Mladen Girazovski

"Actually, OOD is about the opposite"
I wasn't talking about OOD, I mentioned software-design in general. One of the main problems is that OO is a larger "paradigm package" which contains (amongst other concepts) inheritance, static typing, encapsulation and typeclasses (interfaces). Furthermore it is seen as the successor to the procedural paradigm which is the sucessor to whatever.

In practice, however, it is a bit more complicated, and not all the OO-Ideas are really a proof for "better" and more "reusable" design. Other languages like haskell, lisp or google-go have a different view on this affair.

I agree with the rest of your statement, fully aware of the irony that the last 2 paragraphs led even further from the point where this article has started. ;-)

Luis Colorado replied on Wed, 2010/08/04 - 8:51am in response to: Eric Giese

I'm sorry. My response was for Eric. Please see above.

Luis Colorado replied on Wed, 2010/08/04 - 8:53am in response to: Eric Giese

In OO, generality is best achieved by defining a class (or an interface) which serves as an (immutable) data container and another class which knows how to operate on this class (a handler), asking the data container for its information. 

 

Eric,

IMHO, it's an interesting idea (to separate data and logic), but I think it's going a bit too far. Creating a class with data only, and a separate "controller" that operates on the data class seems to me an overkill. First of all, if the data class is only visible to the controller class, why not just put the data inside the controller class?

Secondly, it could be argued that the controller class could then pick the proper data class according to the requirements of the controller class. However, if getters and setters are use inside the class to operate the private properties of the class, instead of invoking them directly using the dot operatior, you obtain pretty much the same advantages of creating a separate class. 

However, I can see the usefulness of your approach if you have data, and multiple methods to operate on the data. This would be analogous to the Collections classes, where you can have a list, and create different classes that use different algorithms to access and manipulate the data.

It doesn't seem to me that your approach should be applied in every situation, because it simply would be an overkill and you would double the number of classes.

Now, if you could explain further your approach and the advantages and disadvantages of it, I would be happy to hear them.

Luis

Jan Kotek replied on Wed, 2010/08/04 - 8:54am

I prefer to write immutable classes with constructors and public final fields (like Case classes in Scale)
But most of time I write getters/setters, it is corporate standard...

 

Eric Giese replied on Thu, 2010/08/05 - 3:27am in response to: Luis Colorado

Since this has nothing to with the article, I'll make it short.

The pattern I described is mostly made for "real" data (contact information...), not for internal calculation values and the like. In my projects, this concept of sending data in a kind of message sending between "handlers" actually works quite well.

I would try to pack all kinds of important "data" your app is working on in separate, immutable classes. As long as you keep them free of other logic (and modifiers), you do not lock your design down into a given path. Also keeping them immutable means you are free to share them between methods, without caring what these methods will do with the data.

The main advantages of this approach are flexibility (you can define new handlers / methods at any time), no inheritance required (neither in the handlers nor in the data), simpler testing (because concerns are separated), no side effects.. Also, its not really my approach, so I am not reinventing the wheel here.

If you are concerned with the complexity: In general, there aren't that many pure data classes as you might expect. Also, I tend to use multiple package private classes in the same class file, if I really need them. ( their indentation looks nicer than those of inner classes ;-) ). As a last point: I rather have a lot of classes with short and self-explaning methods rather than 400-liner imperative gorillas, as i still see regulary on my work.

Maybe I will write an article about this, some time.

Lance Semmens replied on Thu, 2010/08/05 - 9:09am

I would like Java 7 to introduce some syntactic sugar so that my code would look something like:

Person person = new Person(); 
person#name = "harry";
String name = person#name; 

 

And it would be compiled to:

Person person = new Person();  
person.setName("harry");
String name = person.getName(); 

 

Axel Rauschmayer replied on Sat, 2010/08/07 - 7:32am

Check out the addendum to my post (clarifying some of what I’ve written, in response to the comments).

Nils Kilden-pedersen replied on Tue, 2010/08/10 - 8:07am in response to: Oliver Weiler

Except when there is, e.g. JavaSpaces Entry.

Dudu Zerah replied on Tue, 2010/08/10 - 11:28am

I agree with you. Why we produce more methods than needed? Actually, I use Aspectj and SpringRoo to generate getter and setters automatically.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.