views:

756

answers:

22

Why do Java method names use the "get" prefix so extensively? At least in my Java programs there are a lot of methods with names starting with the word "get". The percentage of get-methods is suspiciously high. I am starting to feel that the word "get" is losing its meaning because of inflation. It is noise in my code.

I have noticed that there is a different naming convention being used in functional/declarative programming and PL/SQL. The method name simply states what the method returns. Instead of "account.getAmount()" or "Time.getIsoFormattedDateString(Date date)" they will use "account.amount()" and "Time.isoFormattedDateString(Date date)". This makes perfect sense to me, as the name of the function describes the result of evaluating the method (assuming there are no side effects, which there shouldn't be anyway). The "get" prefix seems superfluous.

I have just started reading the book "Clean Code". It says that methods should do only one thing, and that that thing should normally be one of the following:

  1. Notify some object about an event, typically passing the event as a parameter.
  2. Ask a question about some object, typically with the method name forming a natural language statement, passing the object as parameter and returning a boolean.
  3. Fetch something, possibly passing some lookup key or some object to be converted as parameter and always returning the desired object/value.

My question is about the third category. Are there naming conventions other than "get" for this kind of methods? What criteria do you use when choosing method names/prefixes?

Here is an example:

I have a class with two methods getDates() and getSpecialDates(). getDates() simply returns the value of a private variable (the reference to a collection of dates). This is a standard getter, as I understand it. getSpecialDates() is different; it calls getDates(), fetches a filter from another class, applies the filter and returns what is effectively a subset of getDates().

The method getSpecialDates() could be named computeSpecialDates), findSpecialDates(), selectSpecialDates() or elicitSpecialDates() or whatever. Or I could simply name it specialDates(). And then, for consistency, I could rename getDates() into dates().

Why bother separating between methods that should be prefixed with "get" and methods that should not, and why bother finding replacement words for "get"?

+1  A: 

Personally, I am addicted to get. It is just the human language. When you want something, you want to get something. There is nothing wrong with get prefixes. About the naming convention, I can think of the Select prefix for database queries - SelectUsers for example.

Petar Minchev
As I said in my question, what seems to be wrong with the get prefix is that it often seems unneccessary and is therefore nothing but noise and should thererfore be ommitted.
Arthur Huxley
That's just your opinion, not a fact.
duffymo
+1 with both hands :) If you have 100 methods in your class (or available through the hierarchy), then just typing "yourObjectInstance.get" and wait a bit, forces the Auto Complete in your IDE to filter all the "get" methods. If they didn't start with get it would be much difficult to find the right one. Typical example for this confusion is collection.size() and array.length()
m_pGladiator
+6  A: 

Part of the reason there's so many get* methods is that Java doesn't support "properties" a la .net/COM, and Java beans and such use functions getX and setX to replicate the functionality of a property called X. Some IDEs for Java take advantage of this to allow the setting and retrieval of properties.

cHao
+1 Naked Objects for one is a framework which relies on naming conventions to generate a front end.
APC
Actually (speaking as a Naked Objects committer), that's a pluggable feature. We build up the metamodel using FacetFactorys, and the default factories look for the 'get' prefix. But they don't need to.This design also allows us to support other languages; I got NO working with Groovy a few weeks back, and (as it happens) have started on a Scala one this week. That uses Scala's @BeanProperty annotation.But, to the OP, we don't think there's much wrong with getters either: they are a naming convention that represents a 'know-what' responsibility.-- Dan
Dan Haywood
+5  A: 

One reason is that it is an essential part of the Java Bean Spec.

PartlyCloudy
A: 

I use get and set only for methodes that only get or set a property and not mutch else.

nickik
What do you use for the other methods if not get*?
Arthur Huxley
+15  A: 

It comes from the JavaBeans naming conventions.

John Topley
If Java would add real properties, we wouldn't have to worry about this any more. I'm disappointed that they got removed from the Java 7 proposal.
R. Bemrose
@R. Bemrose: I agree, I wish they would add properties. However, we'd still have to worry about it, all the legacy code and existing libraries/frameworks wouldn't just go away. Plus, it's often hard for people to change their habits. Seems like a LOT of people use `get____` regardless of whether the method can be though of as a property or not.
TM
+1  A: 

Well, although JavaBeans spec asks you to declare getters and setters, I usually will not declare them unless it's absolutely necessary (as in case of many MVC frameworks). I did a lot of swing in my Java career and I tend to declare variables as public (yeah it sounds a bit non OOPy). But I liked it since it looked concise and 'I' know what I'm doing. The only advantage that it had is the reduced number of lines.

Bragboy
+2  A: 

One of the reasons that getter and setter methods are often written in Java is because of the use of JavaBeans conventions.

The standard Java API isn't consistent itself with regard to this, however. For example, class String has a length() method and interface Collection defines a size() method, instead of getLength() or getSize().

Java doesn't support the uniform access principle, so you have to write getter and setter methods to access properties.

Jesper
What do you mean by "Java doesn't support the uniform access principle"? A get() method may return a computed value rather rather than the value of a private variable - instance variables are not intrinsically related to get() or set() methods with the same name
Tarski
@Tarski do you understand the UAP? It means you can access properties in the same way as member vars. So something like `Foo.thingy` would really call `Foo.getThingy()` behind the scenes. The `Foo.thingy` looks as if you're directly accessing a member var, but you aren't. Languages such as C#, Ruby, Scala support this.
Jesper
+4  A: 

One of reasons that require Java developers to use common get/set convention is that many frameworks rely on it for bean creation and setting the fields. For example, if you have some property configured for Spring bean like <property name="foo" value="bar" /> and there's no method named setFoo() in the class, you'll get an error on bean creation.

Vadim Fedorov
A: 

I personally really like getters and setters.

For example if I work with a new API which I'm unfamiliar with and I know I want to retrieve some property is enough if I write in any modern editor smth like obj.get and I'll get an autocomplete list with all the public getter methods and just browse through them. Same for setters.

In most cases I don't even need to open the javadoc ;)

Bogdan
A: 

Java Beans get very sticky to its naming conventions, like suppose you declare a variable name Name, with corresponding setter as setName(). But it would generate an error as, setName must correspond to 'name' instead of Name. Another example boolean isReadey; with getter isReady(). Again error as it look for boolean ready. So, prior to code you must be familiar with this naming convention. But i personally prefer this convention as it makes programmer's work easy and seems to be a bit logical after few moments u spend with it.

rahul jain
+4  A: 

Start using Groovy if you're tired of Java traditions.

Manny
+2  A: 

I am starting to feel that the word "get" is losing its meaning because of inflation. It is noise in my code.

I would slightly disagree with this conclusion. I wouldn't say it loses its meaning, I would say that as it is widely used that methods with the get prefix will do pretty much what you expect them to do.

For the following example:

Time.isoFormattedDateString(Date date)

Does this set the format type based on the input parameter so all subsequent calls will use this format?

I know it is a bit of a stretch that someone would come to that conclusion as it is a static method but would you be as sure if this method was called on an instance? Probably, but the use of get removes all ambiguity:

getIsoFormattedDateString(Date date)

In my opinion, properties are a more elegant solution than dropping get altogether.

David Relihan
Yes, but why not formatDateStringAsIso(Date date) ?
Don Roby
@donroby Yes, in a way I agree for that example. But if you looked at the method name completely out of context would you know what it did? Why remove the "get" prefix when it imediately indicates to any developer what the method will do. That should be the key concern when naming methods.
David Relihan
+2  A: 

As many people have already stated, get..() and set()... are part of the Java Beans Convention. This is necessary for interoperation with other parts of the Java Spec. For example, in JSP you can access members from a Java been by specifying the property name without the get prefix.

Given the bean:-

public class Foo {
  public int getX() { return 1; }
}

We can do the following JSP to get X: -

<jsp:useBean id="aFoo" class="Foo" />
<c:out value="${aFoo.X}" />

Are there naming conventions other than "get" for this kind of methods?

Yes you can use is instead of get for boolean properties.

Tarski
+1  A: 

Historical snippet: If you look at some of the very earliest Java 1.0 APIs (pre JavaBeans), you'll see they don't have the 'get' prefix. For example java.awt.Container#minimumSize() was deprecated in replace by #getMinimumSize().

Dan Haywood
+13  A: 

I personally don't use getters and setters whenever it's possible (meaning : I don't use any framework who needs it, like Struts for instance).

I prefer writing immutable objects (public final fields) when possible, otherwise I just use public fields : less boiler plate code, more productivity, less side effects. The original justification for get/set is encapsulation (make your objects as shy as possible), but in fact, I don't need it very often.

In Effective Java, Joshua Bloch makes this compelling recommendation :

Classes should be immutable unless there's a very good reason to make them mutable... If a class cannot be made immutable, limit its mutability as much as possible.

In the same book, he also says (but I don't want to copy the whole book here) :

The JavaBeans pattern has serious disadvantages.

I totally aggre with that, since JavaBeans were originally intended for a very narrow problem domain : manipulation of graphical components in an IDE. It is a bad practice to use one solution designed for solving another problem.

Jean-Philippe Caruana
Good advice (from a very good book).
ZoFreX
I agree. One of my pet peeves: Someone will say that too much public data is bad because it makes the API complex. I agree. But then he says that the solution is to make them private and create getters and setters. How does that help? Why is saying "x=myObject.someValue" bad but "x=myObject.getSomeValue()" eliminates all the problems? The only good reason I see to use getters and setters is if there are side effects.
Jay
@Jay: It's even worse when `getSomeValue()` returns an Object and people don't realize that someone can now change the state of the object with a getter alone.
Justin Ardini
I agree with "prefer immutable objects" but disagree with the ending conclusions about JavaBeans. The second quote is in regards to calling a bunch of setters for construction vs. using the Builder pattern - not about using JavaBeans in general. JavaBeans is simply a *component* specification. Graphics nor IDEs are required - BeanBox wasn't the purpose of JavaBeans; it was simply an easy way to demo their capabilities. If it's "bad practice to use one solution designed for solving another problem" - stop using Java for developing web apps - Oak was designed to run in TV set top boxes. :P
Nate
@Nate : thanks for your insight
Jean-Philippe Caruana
@Ardini: Absolutely! The general problem of function names that are not just incomplete but outright lies! I once wrote a function that I called "validateStocknumber" that checked if a stock number was valid and returned true or false. Another programmer came along and changed it to also update the stock record, but didn't change the name. Then someone else came along and changed it so that now it doesn't even validate the stock number any more! Arggh!
Jay
It is surely true that solutions developed for one type of problem prove to also be useful for some totally different problem. To give Jean-Philippe the benefit of the doubt, maybe what he meant was that just because a solution is useful for one type of problem shouldn't lead us to blindly use it for other types of problems. Like, Web apps are great for such-and-such types of problems, therefore all new apps should be web apps and no one should ever write a desktop app ever again.
Jay
+2  A: 

What does "get" matter when we live in a day and age where any IDE that's worth having will generate getters and setters for your private variables and lets you fold them up if you'd rather not read them?

Your real issue should be about design: Why do your objects have so many attributes? If your objects have nothing but getters and setters, are you suffering from an "anemic domain model"?

The C# {get, set} notation is marginally better, because it cuts down on the lines of code, but you still have that pesky "get" to type for every variable.

duffymo
A: 

It's important that the "get" prefix remains because:

  • a method should state an action, therefore it must contain a verb in its name

  • get shows that the state of a variable won't change

  • how easy would you distinguish the method account() from the variable account in this expression :

    newAccount = currentAccount + account() --- what does this account() do ?


The reason you see too much getters in your code should worry you!

  • Either you separate your classes to smaller ones or
  • just hide your code better, because you don't have to reveal your classes interns and even should try to hide them as much as you can!
Leni Kirilov
I don't see why a "getter" must state an action: It doesn't do anything, it evaluates to something.In order to show that state does not change you can leave verbs out of the method name.If I saw a method named account() I would assume that it returned an object of whatever type represents an account, say an interface named Account. If I saw a method named amount() I would assume that it returned a number representing an amount. Who wouldn't?
Arthur Huxley
I say that the GET word at the front of a method name isn't something that should cause such a ruckus! And I won't use account() because that would make my program more confusing and ambiguous. I prefer not to left ambiguities in my programs for the ones who read it after me.I personally would easy misread ACCOUNT() as ACCOUNT and I would thought it's not a method...If you decided to drop code-clarity once , you'll do it again later. I think code clarity is more important than a method being 3-characters shorter...
Leni Kirilov
if you read better, I've written "a method should state an action"and since you fight for encapsulation, you use methods and methods should state an action because that's what differs them from variables or types (classes)... again - code clarity.But there is another position - make up your own code-writing conventions and STICK WITH THEM - being consistent is the more important than "is it better to start variables with upper case or lower case"...
Leni Kirilov
Thanks for your input, but I think you are missing my point. There is no need to differentiate between variables on the one hand and methods without side effects that returns something on the other hand. Their semantics are identical in that they represent a value. Syntactically they have to differ by the parentehis () at the end of the method name. Such a small syntactic difference is suitable to give a hint to the _uninteresting_ fact that despite the identical semantics a property's technical implementation is a method instead of a variable.
Arthur Huxley
A: 

I think this is a subset of the "give your variables and functions meaningful names" ideal.

"get" has a specific meaning in Java Beans as many have noted. I think it should therefore be limited to being used to retrieve the value of an internal variable, possibly with side effects. I think it's acceptable if "getting" involves minor computation, like doing a data type conversion or extracting a value from an embedded class or reinterprerting other values, like "public int getRightMargin() { return width-margin.left; }". Any side effects should be limited to things that are truly "side effects" of getting the value, like setting a flag that says it has been retrieved.

But if there's serious computation, I don't think it should be called "get". Maybe "calc" or whatever.

It would be good if we had consistent terms to use in naming functions, like if we all agreed that "read" means that the main activity is to retrieve something from a database while "calc" meant to do calculations or some such. But that might be unrealistic: maybe there are too many cases with subtle differences.

Jay
+1  A: 

As others have mentioned, it is for Java Beans. However, if you are using Java, PLEASE only name a method getXXX() if it only returns a value and does nothing else. Like you hinted at, if it is doing something else, name it something different such as computeXXX().

I sometimes find getXXX() methods with 50 lines of code - if this is the case, you are doing it wrong.

GreenieMeanie
+2  A: 

Method names like getSpecialDates(), computeSpecialDates), findSpecialDates(), selectSpecialDates() and elicitSpecialDates(), to me are commands because of the use of verbs (actions) in their names. Commands are meant to have side effects everytime you call them. Whereas method names like date(), dates(), specialDates() [nouns] are methods that return a useful value with no side effects. Calling the method multiple times returns the same everytime, unless a command is called whose side effect is to change state.

A: 

Premise 1: A method should do only one thing. Premise 2: A getter method - wether it uses the get prefix or not - should have no side effects. Given these two premises I propose: A method whose role is to fetch something and that does so in a relatively simple an inexpensive manner need not have a verb in its's name.

The raison d'etre of a getter is not do something but to evaluate to something. We are not interested in what the method does. Since it has no side effects, whatever computation goes on in the method cannot be of any interest. We are only interested in what the method returns. The method name should reflect that in the form of a noun. Method names consisting only of nouns should always be "getters".

The information in the prefix "get" can be inferred from the lack of verbs. This is simpler and more intuitive than using the get prefix.

A method whose name consists of only a noun and has a return value can be assumed to have no side effects and to be relatively cheap. A method whose name contains a verb and does not have a return value exists to have side effects. A method whose name contains a verb and has a return value can be assumed to be relatively expensive and may have side effects.

It seems the reason everybody is writing "get" all over the place is merely dogmatic tradition originating from the JavaBeans pattern. Leave the get prefix for when you actually plan to use tools/frameworks that need it!

Arthur Huxley
A: 

One option is to keep the get prefix for methods that return primitive or immutable values, but drop the prefix for methods that return references that can be used to modify the original recipient.

e.g. in java.util.Map, size() could be called getSize() but keySet() would not be called getKeySet().

finnw