В Java вы можете использовать шаблон компоновщика с обязательными и переназначаемыми полями?

Это связано со следующим вопросом:

Как улучшить шаблон строителя?

Мне интересно, возможно ли реализовать конструктор со следующими свойствами:

Некоторые или все параметры обязательныНи один метод не получает много параметров (то есть, нет списка значений по умолчанию, предоставленных начальному заводскому методу компоновщика)Все поля построителя могут быть переназначены произвольное количество разКомпилятор должен проверить, что все параметры были установленыМожно требовать, чтобы параметры были первоначально установлены в некотором порядке, но как только любой параметр установлен, все последующие компоновщики могут снова установить этот параметр (то есть вы можете переназначить значение любого поля компоновщика, которое вы хотите)Для сеттеров не должно быть повторяющегося кода (например, нет переопределяющих методов сеттера в подтипах компоновщика)

Одна неудачная попытка приведена ниже (пустые частные конструкторы опущены). Рассмотрим следующую реализацию игрушечного конструктора и обратите внимание, что в строке с "Foo f2" есть ошибка компилятора, потому что унаследованный установщик для возвращает BuilderB, а не BuilderFinal. Есть ли способ использовать систему типов Java для параметризации возвращаемых типов сеттеров для достижения вышеуказанных целей или достижения их каким-либо другим способом.

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();
    }

}

Ответы на вопрос(5)

Ваш ответ на вопрос