10

For example, I have a class with a builder with 5 params, instead of me manually selecting the params and populating them, is there a way to tell Intellij to do this:

MyClass myClass = MyClass.builder()
                   .param1()
                   .param2()
                   .param3()
                   .param4()
                   .param5()
                   .build();

Then I can just fill in the parameters myself. It'd be handy to make sure I haven't missed any.
Alternatively, can I set the autocomplete options to sort in the order they appear in the class?

mal
  • 3,022
  • 5
  • 32
  • 62
  • 1
    you should not do it this way - better provide validation in your `build` method – m.antkowicz Dec 02 '18 at 12:30
  • 1
    OK, that makes sense, validate required parameters in the build method itself, of course. care to write an answer? (Even still, this would be a nice feature to have to save time) – mal Dec 02 '18 at 12:31
  • to be honest I don't believe it would save your time - you need still to manually provide parameters for such calls and IntelliJ autocompletion seems to work 'good enough' :) – m.antkowicz Dec 02 '18 at 12:36

2 Answers2

1

Even if there is such a plugin I believe it would not help you really (because you still need to manually click on every method call and provide parameter) and you should definitely not use IDE to protect you from not setting all mandatory parameters.

In this case you this either put all mandatory params to the constructor or provide a validation inside build method. Something like

public MyClass build() {
    if(param1 == null) {
        // handle param1 null value
    }
    if(param2 == null) {
       // etc
    }
    ...
}
m.antkowicz
  • 13,268
  • 18
  • 37
-1

To make sure, that you don't miss any parameter, you can use a specific variation on builder pattern. I call it "Named parameters":

public final class MyClassBuilder {
    public static Param2 param1(String param1) {
        return param2 -> param3 -> param4 -> param5 -> new MyClass(
            param1, param2, param3, param4, param5
        );
    }
    public interface Param2 {
        Param3 param2(String value);
    }
    public interface Param3 {
        Param4 param3(int value);
    }
    public interface Param4 {
        Param5 param4(boolean value);
    }
    public interface Param5 {
        MyClass param5(Object value);
    }
}

Usage is then like this:

MyClass m = MyClassBuilder.param1("1")
                          .param2("2")
                          .param3(3)
                          .param4(false)
                          .param5(new Object());

With this pattern the compiler (and any IDE) will enforce order of parameters, and invoking all of them, as any intermediate state is not alowing to get the result. It also doesn't require any extra build() method, as the last parameter is already able to return the result.

It's a bit more coding, but I plan to create a code generator for it within my project: https://github.com/c0stra/fluent-api-generator

Ondřej Fischer
  • 411
  • 1
  • 7
  • 16
  • 1
    Does not address the question asked. Also this pattern is very obscure and very verbose.. even for Java – Colm Feb 27 '23 at 15:46
  • Can you explain a bit, what you mean? This answer answers highest number of points in the question. Not the first one abou IDE filling the code for you (no answer here does), but points about ensuring all parameters and enforcing their order are both answered (other answers answered only one point, and actually only at runtime). And regarding verbosity, did you compare the code with "traditional" builder, with all the methods and backing fields and the runtime check o all of them in the build method (not talking about necessary unit tests because of runtime solution)? – Ondřej Fischer Feb 28 '23 at 19:32
  • I agree that the other answer (there is only one other answer) is not very useful, but neither is it a step in the wrong direction. My main concern with this bespoke builder is maintenance. Simple additions will be difficult and hard to debug. Errors will be obscure. The public constructor can be abused to skip your enforced ordering and It's not obvious how to do input validation in the builder. Yes this is clever but clever code is not the goal. Maintainable, extensible, testable code is the goal. – Colm Mar 01 '23 at 12:33