A better approach might be to use a Builder, as described in Effective Java 2nd Edition in Item 2.
The basic idea is to have a Builder class that has setters (but usually not getters) for the different constructor parameters. There's also a build()
method. The Builder class is often a (static) nested class of the class that it's used to build. The outer class's constructor is often private.
The end result looks something like:
public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}
public Builder setId(int id) {
this.id = id;
return this;
}
// you can set defaults for these here
private int id;
}
public static Builder builder() {
return new Builder();
}
private Foo(Builder builder) {
id = builder.id;
}
private final int id;
// The rest of Foo goes here...
}
To create an instance of Foo you then write something like:
Foo foo = Foo.builder()
.setId(id)
.build();
You can also split this up, of course:
// I don't know the ID yet, but I want a place to store it.
Foo.Builder fooBuilder = Foo.builder();
...
// Now I know the ID:.
fooBuilder.setId(id);
...
// Now I'm done and want an immutable Foo.
Foo foo = fooBuilder.build();
You can have multiple setters on the builder, and even add additional parameters to build() or the Builder's constructor.
This lets you have a mutable object while parsing, but switch to an immutable object when you're finished. Your API only ever need expose the immutable object in many cases.