Java 生成器模式中静态类的成员应该是最终成员吗?

Java 生成器模式中静态类的成员应该是最终成员吗?,java,final,builder,Java,Final,Builder,因此,我看到了几个关于构建器模式的示例。总之,静态类或构建器只有那些可以由构造函数初始化的成员作为final。示例- public class User { private final String firstName; // required private final String lastName; // required private final int age; // optional private User(UserBui

因此,我看到了几个关于构建器模式的示例。总之,静态类或构建器只有那些可以由构造函数初始化的成员作为final。示例-

public class User {
        private final String firstName; // required
        private final String lastName; // required
        private final int age; // optional

    private User(UserBuilder builder) {
            this.firstName = builder.firstName;
            this.lastName = builder.lastName;
            this.age = builder.age;
            this.phone = builder.phone;
            this.address = builder.address;
        }

    public String getFirstName() {
            return firstName;
        }

    public String getLastName() {
            return lastName;
        }

    public int getAge() {
            return age;
        }

    public static class UserBuilder {
            private final String firstName;
            private final String lastName;
            private int age;

    public UserBuilder(String firstName, String lastName) {
                this.firstName = firstName;
                this.lastName = lastName;
            }

    public UserBuilder age(int age) {
                this.age = age;
                return this;
            }
         }
    }

为什么只有名字和姓氏是最终的,可以由构造函数初始化?然后就不能设置了?我的疑问是,我能不能从First和Last中删除final,让构造函数初始化所有三个成员,并在类中设置相应的setter?

这里的设计是,名字和姓氏总是必须设置,但年龄是可选的。(我本想在这里使用
Integer
,而不是默认值为0……但无论如何,我还是更喜欢使用
生日
,但我离题了。)

“必需vs可选”部分是通过强制名字和姓氏出现在构造中来传达的。。。那你为什么还要二传手呢?您希望何时在构造函数中将第一个名称设置为一个对象,然后对其进行更改


您可以将字段设置为非最终字段并添加setter。。。我只是觉得这不是一件特别好的事情。这不是什么失败的问题,只是通过API设计传达的内容发生了变化。

如果成员现在可以被setter访问,那么它就不再是一个构建器了,是吗?@kolossus:是的,是的-构建器的全部要点通常是它是可变的,而构建的对象是不可变的。谢谢@jon的回答。我明白你的意思。但从理论上讲,在构建器模式的情况下,如果我们忘记了这个特殊情况,我们是否只初始化那些在构建过程中需要的字段?@Vwin:我不明白你在问什么。如果一切都是可选的,那么您通常会有一个无参数构造函数-这就是您的意思吗?但是,什么是真正的可选性总是值得考虑的。很抱歉,我弄糊涂了。我的意思是我们可以在构造函数中初始化可选参数吗?然后他们有二传手吗?这是一种好的做法吗?