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.

3 thoughts on “Java Bean Getters/Setters

  1. frightanic

    I don’t see what the “private String iMessageId”-case has got to do with ‘java.beans.Introspector#decapitalize’. There’s nothing to decapitalize in ‘iMessageId’ and hence this doesn’t explain why the getter turns out to be ‘getiMessageId’.

    Reply
    1. tompson Post author

      you have to think “the other way around”:

      If you would make the getter getIMessageId the decapitalize method would look at IMessageId and decide there is nothing to decapitalize – so it returns IMessageId and this property does not exist.

      Reply

Leave a Reply