I noticed that you mentioned a a number of approaches, and during the years since the question was asked, one alternative wasn't really explored - the Builder
design pattern.
The idea is that with a builder you only set those parameters that you need, and it scales very well as the number of arguments grows (as opposed to overloading).
Here's an example of a class you could use:
public class Something { private String p1; private Integer p2; private Something(String p1, Integer p2) { this.p1 = p1; this.p2 = p2; } public static class Builder { private String p1; private Integer p2; public Builder setP1(String value) { this.p1 = value; return this; } public Builder setP2(Integer value) { this.p2 = value; return this; } public Something build() { // Validate input and set defaults here return new Something(p1, p2); } }}
Here's how you'd use it:
var something = Something.Builder().setP1("blah").setP2(12345).build();calculate(something); // or something.calculate()
Now you may notice that the above implementation contains a fair amount of boilerplate code, which is its main downside. Having said that, there are libraries that eliminate it for you, e.g. FreeBuilder, making the code short and tidy (relatively speaking - Java isn't known for its code compactness).