tags:

views:

194

answers:

6

I am writing some immutable types in Java and wonder about how to name the accessor methods. The Java Bean specification says that the names of accessors should be getX or isX, but since the fields are final, there is no setter and the fields are more like attributes than properties.

There for I'd prefer naming the getter methods like:

public T x()

rather than

public T getX()

Please note as an example:

public int java.lang.String#length()

(Which might have been specified so early in the Java history, so the conventions where not there yet.)

The immutable objects expose means to create modified versions of themselves through methods which I've tried to name like a verb rather than MyObject MyObject#setX(), this should limit the risk of the user calling setX() and think that the object has changed. So: MyObject MyObject#shine(newShineLevel).

This is not always possible easy though. How would you name a method for adjusting an endpoint in a rectangle other than Rectangle.setUpperLeft()? Rectangle.adjustUpperLeft maybe, but now we're just moving away from the conventions.

I guess the question is relevant for all languages, but this questions concern Java in particular.

+5  A: 

Even for immutable types, the convention getX() still stands. Some examples:

  • java.lang.Integer.getInteger()
  • java.lang.Boolean.getBoolean()

It is true that there are also many examples such as java.lang.String.length(), but the common convention is to use getX. Just as mentioned in the answer below, it is crucial to separate between an atomic get operation, and a method which does some calculations on the data.

Also worth mentioning that plain java beans in many frameworks depend on the fact that getters/setters are conveniently named getX and setX.

Yuval A
Why is it important to know the difference between computed and "stored" value? Isn't that kind of the reason to have the accessor methods to start with, instead of directly exposing the inner variable
Hugo
Simply in terms of readability. You would expect a getter to simply be gateway to an encapsulated member, and not have to be surprised when profiling your app to find out that some `getX()` is a major bottleneck since it is doing some surprising calculations you would not expect from a getter.
Yuval A
Ehm, `getInteger` and `getBoolean` aren't getters (they take arguments and are static), and if you look at the non-static methods of those classes, you find `booleanValue`, `intValue`, etc. Also, the entire point of having accessor methods is that you *want* to be able to hide if a value is stored in a field or if it is an aggregated value, so that you can change the implementation without the interface. Extremely computationally intense calculations shouldn't pretend to be accessors, of course, but field accesses and simple calculations are both good candidates for hiding behind accessors.
gustafc
Java beans allows other names for these methods. `getXxx` and `setXxx` is just the default.
Tom Hawtin - tackline
+6  A: 

The convention in Java for accessing properties of a class -- including immutable classes -- is to use the get and set prefixes so I would recommend using public final T getX().

The reason the length() method on a String isn't called getLength() is because there is no property called length on the String class.

Olly
it might be called count or size internally (I believe it was count), but I'm pretty sure it stores that information somewhere, so I wouldn't say that length() is a method which performs calculations. Even if it wasn't stored, exposing that fact in the naming would basicaly expose implementation details which somehow defeats the encapsulation, so I don't think that way of justifying the naming is flawed either way
Grizzly
I've just checked and you're right, length indeed just returns the value of the 'count' attribute so I've updated my response accordingly, but my point about there being no attribute named 'length' still stands.
Olly
When you say "property", do you mean "field" then? If so, what does the name of the field have to do with the naming of the accessor method? Properties (`get` and `set` pairs) can be used for other purposes besides providing access to fields, like simple calculating simple aggregated values, to enforce the "Law of Demeter", etc.
gustafc
+6  A: 

If these classes may be used with any reflection based framework then you are better off staying with the getX convention. For example, accessing properties in JSPs and other templating systems via an expression "x.y" requires that the object have a method getY().

tdavies
Excellent point. I have been following the recommendation so far, but kinda wanted to get away with removing those three annoying characters. I think its exposing internals to say what accessors correspond to instance variables and which ones expose calculations
Hugo
+4  A: 

People tend to down-vote me when I say this, but the get prefix is really only mandatory if you're writing a bean. There are lots of examples of where get is not used. not only String.length(). You find it in the primitive wrapper classes (intValue(), doubleValue(), booleanValue(), ...), enums (name() and ordinal()) and collections (size()), and the way annotations were design also seems to encourage the get-less style. (Josh Bloch covers the subject in Effective Java, and advocates the more readable get-less style unless you're actually writing a bean.)

So: Use the get prefix and your object can be used as a bean. Ditch it, and your code gets easier to read. It's up to you to decide what you think is more important.

Myself, I usually use the prefix even though I dislike it, simply because Eclipse auto-generates it for me :)

gustafc
+1.In Google Collections I follow Josh's advice -- use get when you have a true get-and-set pair, for example Map.Entry has getValue() and setValue(). And use get when it would be way too weird not to, for example Map.Entry's third method is getKey() because key() would stick out. Other than that, get is an absolutely useless prefix. Does anyone really wish they had to say Iterator.getNext()?
Kevin Bourrillion
+1 indeed. Use it for consistency if required, but it is (as you say) a convention for JAVABEANS. There's a weird persistent belief that every object in your system has to be a JavaBean -- JavaBeans are specific objects for specific purposes (see the first paragraph of http://en.wikipedia.org/wiki/JavaBean) and there's no real reason to follow those conventions unless you're writing one.
Cowan
A: 

I'd stick with the "get" convention simply because so many other tools work with it. Jakara Commons BeanUtils for example. Lots of tools/libraries will work by default if you have the right naming, but require configuration if you've deviated from the bean accessors convention.

I'm not disagreeing with you reasoning for deviating, I just think you're probably better off in the long run sticking with the get/set convention.

Chris Kessel
A: 

It's a good idea to use get--never mandatory, but people will automatically know what it's for.

Get does not imply that you have that as a member variable, in fact it's supposed to hide that fact. It can easily be giving access to a computed value.

size(), length(), etc were created before Borland found they needed the get/set concept to implement their GUI builder (I'm not sure exactly who came up with the idea, but that was the reason).

intValue, doubleValue etc are not getters, they are converters and therefore are named differently.

Now, all that said, if you really want to use x or getX it is your choice. getters and setters are no longer needed for most decent toolsets, they will use annotations instead--just be ready for a few people to take a few extra seconds typing "get" followed by "ctrl-space" and not finding what they are after.

Bill K