Em java, você pode usar o padrão do construtor com campos obrigatórios e reatribuíveis?

Isso está relacionado à seguinte pergunta:

Como melhorar o padrão do construtor?

Estou curioso para saber se é possível implementar um construtor com as seguintes propriedades:

Alguns ou todos os parâmetros são necessáriosNenhum método recebe muitos parâmetros (ou seja, nenhuma lista de padrões fornecidos ao método inicial de fábrica do construtor)Todos os campos do construtor podem ser reatribuídos um número arbitrário de vezesO compilador deve verificar se todos os parâmetros foram definidosNão há problema em exigir que os parâmetros sejam configurados inicialmente em alguma ordem, mas depois que qualquer parâmetro for definido, todos os construtores a seguir poderão ter esse parâmetro definido novamente (ou seja, você pode reatribuir o valor de qualquer campo do construtor que desejar)Nenhum código duplicado deve existir para setters (por exemplo, nenhum método de setter de substituição nos subtipos de construtor)

Uma tentativa falhada está abaixo (construtores privados vazios omitidos). Considere a seguinte implementação do construtor de brinquedos e observe que a linha com "Foo f2" tem um erro de compilador porque o setter herdado de um retorna um BuilderB, não um BuilderFinal. Existe uma maneira de usar o sistema de tipos java para parametrizar os tipos de retorno dos levantadores para atingir os objetivos acima, ou alcançá-los de outra maneira.

public final class Foo {

    public final int a;
    public final int b;
    public final int c;

    private Foo(
            int a,
            int b,
            int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public static BuilderA newBuilder() {
        return new BuilderC();
    }

    public static class BuilderA {
        private volatile int a;

        public BuilderB a(int v) {
            a = v;
            return (BuilderB) this;
        }

        public int a() {
            return a;
        }
    }

    public static class BuilderB extends BuilderA {
        private volatile int b;

        public BuilderC b(int v) {
            b = v;
            return (BuilderC) this;
        }

        public int b() {
            return b;
        }
    }

    public static class BuilderC extends BuilderB {
        private volatile int c;

        public BuilderFinal c(int v) {
            c = v;
            return (BuilderFinal) this;
        }

        public int c() {
            return c;
        }
    }

    public static class BuilderFinal extends BuilderC {

        public Foo build() {
            return new Foo(
                    a(),
                    b(),
                    c());
        }
    }

    public static void main(String[] args) {
        Foo f1 = newBuilder().a(1).b(2).c(3).build();
        Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
    }

}

questionAnswers(5)

yourAnswerToTheQuestion