Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntelliJ IDEA: simple way to create type-safe builder without plugins?

Using IntelliJ IDEA, I want to create a POJO class that helps me avoid making silly mistakes, in terms of getting parameters around the wrong way.

  • I don't care about other IDEs
  • I don't want to use any form of reflection (i.e. no Lombok or similar)
  • I don't care about the JavaBean standard
  • I don't care about "best practices"

I just want to create a class, declare some fields and have a convenient way to create said class that reduces the likelihood that I will get same-type parameters the wrong way round when I create the class.

Starting with this:

public class TestObject {
  public String x;
  public String y; 
}

I want to generate something I can use, like this:

TestObject o = new TestObject().setX("x").setY("y");

or this:

TestObject o = TestObjectBuilder.withX("x").withY("y").build();

I don't mind if there's a separate builder class (prefer to jam all the methods on the original class, but no biggie).

I don't mind if it makes many copies along the way. Prefer if the whole process creates only 1 instance, like my solution below; but if the solution takes an immutable instance-per-setter-field approach - no biggie.


Here's what I currently do to achieve this goal.

(1) Use IDEA to Generate constructor, selecting all fields, resulting in this:

public class TestObject {
  public String x;
  public String y;

  public TestObject(String x, String y) {
    this.x = x;
    this.y = y;
  }
}

(2) Refactor Constructor with Builder, having to select Use existing, then copy/paste the TestObject name into the field, because why not, resulting in:

public class TestObject {
  public String x;
  public String y;

  public TestObject(String x, String y) {
    this.x = x;
    this.y = y;
  }

  public TestObject setX(String x) {
    this.x = x;
    return this;
  }

  public TestObject setY(String y) {
    this.y = y;
    return this;
  }

  public TestObject createTestObject() {
    return new TestObject(x, y);
  }
}

(3) Manually delete the constructor (because its presence denies use of the default ctor) and delete the createTestObject() method (because it's superfluous, Java gives me a clone method for free). Leaving me with this little beauty, which is all I wanted in the first place:

public class TestObject {
  public String x;
  public String y;

  public TestObject setX(String x) {
    this.x = x;
    return this;
  }

  public TestObject setY(String y) {
    this.y = y;
    return this;
  }
}

How about it, Obi-wan Stack-overflow, is there a way to do this with less pfaffing about?

Another thing I'd like to be able to do is add fields with less pfaffing about. At the moment, when I add a field I'm doing generate setter the modifying the result by hand to be in line with the other setters - is there a better way to do that?

like image 927
Shorn Avatar asked Jan 30 '26 23:01

Shorn


1 Answers

Yes, it's possible.

  1. Press Alt-Insert (or "Code" -> "Generate") to open "Generate" menu
  2. Select Setter.
  3. In the next window select "Builder" in the top drop-down menu called "Template" (by default it's "intellij Default" there).

You'll achieve exactly the same result that you want.

like image 158
amseager Avatar answered Feb 01 '26 11:02

amseager



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!