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.