Generate Chainable Setters with IntelliJ IDEA

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:

  1. Return type changed from void to $class.name
  2. Method prefix changed from set to with
  3. 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);