I prefer my setteers to be chainable so I changed the default IntelliJ IDEA template to get what I want. Here’s how I did it
The rules: Our setters must start with with
(instead of set
)
and return this
at the end.
Open up the code generator (Alt+Insert)
In the setter generator dialog, click the button with the three dots ⋮ next to the scheme field. Copy the default scheme (IntelliJ Default) and paste in the following:
#set($paramName = $helper.getParamName($field, $project))
#if($field.modifierStatic)
static ##
#end
$class.name with$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))(final $field.type $paramName) {
#if ($field.name == $paramName)
#if (!$field.modifierStatic)
this.##
#else
$classname.##
#end
#end
$field.name = $paramName;
return this;
}
What happened here? Three things:
- Return type changed from
void
to$class.name
- Method prefix changed from set to with
return this;
was added at the end.
#end
- void set$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))($field.type $paramName) {
+ $class.name with$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))(final $field.type $paramName) {
#if ($field.name == $paramName)
#if (!$field.modifierStatic)
this.##
#else
$classname.##
#end
#end
$field.name = $paramName;
+ return this;
}
Why You’d Want to Do That
The canonical setter form, generated by IntelliJ IDEA, is the following
public void setThing(Thing thing){
this.thing=thing;
}
This leads to the familiar construct of:
foo.setThing(thing);
foo.setAnotherThing(another);
foo.setThat(that);
I believe that almost all void
methods can (and should) return the same object instead. This is certainly the case with setters, which are well-known constructs with no special logic to them.
Consider the following setter pattern:
public Foo withThing(Thing thing){
this.thing=thing;
return this;
}
which enables us to do
foo.withThing(thing).withAnotherThing(another).withThat(that);