So we all know the bean/POJO get/set convention right? Its fine for mutable objects, but what about immutables? The convention just doesn't work there.
BigDecimal base = new BigDecimal(100d); base.setScale(2); // BUG!!!
Why is the above a bug? Because BigDecimal
is immutable, and so the set method doesn't actually change base
. Instead, the method returns a new BigDecimal
instance which isn't being assigned in the example. Here's the fixed version:
BigDecimal base = new BigDecimal(100d); base = base.setScale(2); // FIXED by assigning
In addition, by returning a new instance, the set method actually breaks the JavaBean spec. This is because the JavaBean spec says that set methods must return void.
So what can be done? Well I'd like to argue that the time has come for a new coding convention for immutable beans/POJOs. As a convention (preferably Sun endorsed) it would allow frameworks like JSF or Struts to handle immutable objects properly. So, what do I propose?
Mutable verb | Immutable verb |
---|---|
get | get |
set | with |
add | plus |
subtract | minus |
Here's an example of a datetime object using these conventions:
DateTime dt = new DateTime(); // immutable get is the same as a mutable get int month = dt.getMonthOfYear(); // immutable sets use the 'with' verb dt = dt.withYear(2006); dt = dt.withMonthOfYear(5); dt = dt.withDayOfMonth(23); // immutable add or subtract using the 'plus'/'minus' verbs dt = dt.plusYears(1); dt = dt.minusDays(1); // combinations, for example, the first day of the next month dt = dt.withDayOfMonth(1).plusMonths(1);
If adopted as a standard, there is even the potential to write a PMD or FindBugs rule to match on the verbs and ensure that you actually assign the result, thus eliminating a potential bug.
So, do you use immutable objects? Do you have a coding convention like this? Should this become a Sun convention? Opinions welcome!