简体   繁体   中英

Generate setters that return self in Eclipse

I'd like to have my setters so that I can chain them like:

myPojo.setX(x).setY(y);

Usually I generate setters with Eclipse but unfortunately code template for setters allows me to change only the body of the setter, not the signature.

What would be the easiest way to complete the above? Besides search-and-replace + manual editing? :)

You could use the Editor/Templates for this purpose. To define a new Template open the Preferences Window, then Java->Editor->Templates. In this window you can define a new template and give it a name. For example:

public ${enclosing_type} setName(${argType} name) {
    this.name = name;
    return this;
}

Give it a name, eg settr. You can then use this template in your java code by typing 'settr' and then Ctrl-Space.

I can offer a kind of patch that however does not require any additional installations.

Go to Window/preferences/Java/Code Style/Code templates. Edit "setter body" template as following:

${field} = ${param};
return this;

Now when you run "generate getters and setters" it will create setter like:

public void setMyField(String myField) {
    this.myField = myField;
    return this;
}

This obviously cause compilation error because the method type is void . But you can strike Ctrl-F and replace all 'public void set' by public YourClassName set .

It is a patch, but it works...

您可以使用fluent-builders-generator插件以您希望的方式生成setter。

Notepad++ solution:

Data:

JavaType variableName;

Search regex:

(.*) (.*);

Replace regex

public JavaType with\2\(\1 p\2\) { this.\2 = p\2; return this; }

You have to manually correct method name, since it does not uppercase the first letter of variable name.

I use withField naming pattern with this template

public ${enclosing_type} with${Field}(${argType} ${param}) {
    set${Field}(${param});
    return this;
}

I think it was inspired by @paweloque 's answer at the time. The only differences are the added {$Field} and ${param} which are used to name the method and arguments and call the real setter generated by eclipse in the method body.

What's great about templates is that you can create your with methods using the autocomplete plus a few tabs while filing up the template's variables.

The result is something like this :

public Foo withBar(String bar)
{
    setBar(bar);
    return this;
}

Here is a screenshot to set this up in eclipse:

在此输入图像描述

My two cent on this, I (miss)use the

Preferences > Java > Code Style > Code Templates > Comments > Setter

and put there the following template:

/**
 * @param ${param} the ${bare_field_name} to set
 */
// public ${enclosing_type} ${bare_field_name}(${field_type} ${param}) {
//     ${enclosing_method}(${param});
//  return this;
// }

Benefit:

  • It can be used when generating getters setters using

     Source > Generate Getters and Setters... 
  • It can be used when generating a single setter while typing in the editor set<start-of-fieldname> and hitting Ctrl + Space .

Drawbacks:

  • You have to tick generate comments when generating getters setters.
  • You have to remove the line comment starters, Ctrl + F // and replace with empty string.

Unfortunately, I could not find a way to uppercase the first letter of the field name which would have made using a prefix such as with possible.

One alternative would be to use Lombok's @Setter and @Getter . Lombok enhances your classes at compiled based on some annotations. It works well on the command line and it has Eclipse support.

@Getter @Setter
public class Point {
    int x, y;

    static void test() {
        new Point().setX(1).setY(2);
    }
}

And in lombok.config :

lombok.accessors.chain=true

With JavaForger you could use the template as given below to generate the setters. It does mean that you'll have to run a main method for every class that you want generate getters and setters for.

<#list fields as field>
  /**
   * Sets the ${field.name} of the {@link ${class.name}}.
   *
   * @param ${field.name} The input {@link ${field.nonPrimitiveType}}. 
   */
  public ${class.name} ${field.setter}(${field.type} ${field.name}) {
    this.${field.name} = ${field.name};
    return this;
  }
</#list>

The code below executes the template above (setters.javat) for a class called "myClass.java" and merges the generated code with the inputclass. It will override existing setters if they exist.

JavaForgerConfiguration config = JavaForgerConfiguration.builder()
  .withTemplate("setters.javat")
  .withMergeClassProvider(ClassProvider.fromInputClass(s -> s))
  .withOverride(true)
  .build();
JavaForger.execute(config, "myClass.java");

You will have to add the location of "setters.javat" with:

StaticJavaForgerConfiguration.addTemplateLocation("my/location/");

The project can be found here: https://github.com/daanvdh/JavaForger .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM