【问题标题】:Immutable classes fields queries不可变类字段查询
【发布时间】:2017-10-15 06:18:32
【问题描述】:

我有几个与immutable 类字段相关的问题。

假设我有一个班级Student

public class Student {

    private final int empId;
    public int getEmpId() {
        return empId;
    }

    public Student(int empId) {
        this.empId=empId;

    }
}

问题1:为什么必须将字段定义为privatefinal?

问题 2:为什么需要 finalprivate。当我们将字段声明为final 时,它不会在类外可见?

问题 3:为什么我们不能做到public final

提前致谢。

【问题讨论】:

    标签: java immutability private final


    【解决方案1】:

    问题 1:为什么必须将字段定义为 private final?

    因为否则有可能添加修改字段的代码,然后它就不再是不可变的了。

    问题 2:为什么需要 final 和 private。当我们将字段声明为 final 时,它不会在类外可见?

    最后一句话不是真的;创建字段final 不会使其在课堂外不可见。 private 关键字的作用是使其在课堂外不可见。

    问题 3:为什么我们不能将其公之于众?

    您可以将其设为public final,但字段通常应为private,并且只能通过类内的方法直接访问。

    【讨论】:

    • q1) 并非严格正确,因为公共最终 int 无法修改
    • 您好,感谢您的回复。对于第 2 点,我的意思是私人输入错误。问题 2:为什么需要 final 和 private。当我们将字段声明为 PRIVATE 时,它在类外不可见?
    • @KamalVerma private 与类是否不可变没有直接关系。关于不可变的一点是:在对象被构造和初始化之后,它应该不可能改变状态(成员变量)。
    【解决方案2】:

    问题 1:为什么必须将字段定义为 private final?

    不,不是。 final 足以实现不变性。

    问题 3:为什么我们不能将其公之于众?

    我们可以做到。
    在您的示例中,int empId 是开箱即用的不可变的(与任何原语一样)。
    因此,将 empId publicprivate 声明为 final 时不会更改 Student 的状态(在包含它的类的实例化后不可重新分配)。

    一般来说,不建议为字段提供 public 修饰符,因为它违反了 OOP 的封装原则。

    问题 2:为什么需要 final 和 private。当我们 将字段声明为 final 它将在类外不可见?

    不,final 修饰符仅执行上面描述的操作,但无论如何,正如您所解释的那样,在您的情况下(原始),使该字段可见或不可见对它的不变性没有影响,而它是 final

    【讨论】:

    • “一般来说,不建议为字段提供 public 修饰符,因为它破坏了封装原则机制” getter 以同样的方式破坏封装
    • @Michael 大多数时候是的。但它有区别:使用方法获取值非常灵活,因为它允许使用多态性、逻辑、验证、缓存等......你不能通过字段访问来做到这一点。
    • 根据定义,getter 总是会破坏封装。您真正要说的是,声明它public 不如提供getter 灵活。无论哪种方式,封装都被破坏了。
    • 根据定义?但是你指的是哪个定义?我理解你的观点,但我认为你概括了一点。对所有字段使用哑 getter 会以某种方式破坏封装,但如果类 API 旨在返回某些值,则为需要的字段提供 getter 是很好的。
    • 封装是不暴露对象包含的数据的原则。 Getter 公开对象包含的数据。我并不是说吸气剂不是有时 必要的或总是 一个糟糕的主意。我说过它总是会破坏封装。
    猜你喜欢
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多