Java Bean Getters/Setters
Many Java developers think they know everything about Java Beans and the correct getter/setter styles, but there are some hidden traps 😉
Let’s do a little quiz!
How should the correct and getter/setter for a property with the following field look like?
private String name;
This is an easy one:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Notice that the first letter of the field was made uppercase.
Here is a different one:
private String URL;
The correct getter/setter methods would look like:
public String getURL() {
return URL;
}
public void setURL(String URL) {
this.URL = URL;
}
In this example the field was already uppercase so nothing was changed in the getter/setter.
So what’s about a field like this:
private String iMessageId;
This one is a little bit tricky - could you guess the correct getter/setter?
public String getiMessageId() {
return iMessageId;
}
public void setiMessageId(String iMessageId) {
this.iMessageId = iMessageId;
}
It is important that the case was not changed - like for the URL field. This happens when the second letter of the field name is already uppercase.
The reason for this is the method java.beans.Introspector.decapitalize
:
/**
* Utility method to take a string and convert it to normal Java variable
* name capitalization. This normally means converting the first
* character from upper case to lower case, but in the (unusual) special
* case when there is more than one character and both the first and
* second characters are upper case, we leave it alone.
*
* Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
* as "URL".
*
* @param name The string to be decapitalized.
* @return The decapitalized version of the string.
*/
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
I guess this one was new to some of you, wasn’t it?
The last example applies to boolean properties. We know that the getter/setter for
private boolean active;
may look like
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
or
public boolean getActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
But not everybody knows that the getter/setter for a property of the type Boolean:
private Boolean closed;
must look like
public Boolean getClosed() {
return closed;
}
public void setClosed(Boolean closed) {
this.closed = closed;
}
the getter isClosed()
would not be recognized.
Not to long ago even Eclipse code generators made mistakes with those edge cases - I checked today and both IntelliJ and Eclipse generated everything correct. If you want to look into the specification you can do this here.