【问题描述】:

我正在为一个类编写一个 equals(Object obj) 函数。我看到可以从调用者访问 obj 的私有字段。所以不要使用吸气剂:

Odp other = (Odp) obj;
if (! other.getCollection().contains(ftw)) {

}

我可以直接访问该字段:

Odp other = (Odp) obj;
if (! other.collection.contains(ftw)) {

}

这是不好的做法吗?

【问题讨论】:

标签: java scope private member


【解答1】:

我倾向于总是使用 getter,因为有时 getter 不仅仅是“return(foo)”。有时,如果它们为空,它们会初始化事物,或者在其中进行一些调试日志记录,或者以某种方式验证当前状态。它更加一致。

【问题讨论】:

  • +1 如果出于某种原因可以将“集合”重命名为更清晰的状态,我宁愿在一个地方更改它,而不是在每个使用 getter 的地方。
【解答2】:

不,不是。私有变量和方法无法从其他类访问的原因是允许您更改类的内部结构,而不必更改使用该类的所有代码(以及防止您的类的用户例如设置变量到一个它不应该有的值)。

如果您使用其他对象的私有变量不会造成任何损害,因为如果您要重构类的内部结构,则无论如何您都必须更改类内部的代码。

【问题讨论】:

  • 仅仅因为它会在 99% 的时间内工作并不意味着它是正确的做法。它打破了封装并将类更紧密地结合在一起,除了节省键入五个字符之外没有其他原因。请看我的回答。
  • “将类更紧密地结合在一起” - 哪些类?这里只涉及一个类,您不能将一个类与其自身“解耦”。
  • 不一定。传递给 equals() 的参数不一定是完全相同的类。
  • 我不同意这个答案。最好使用访问器。
  • 访问器可能会做一些特殊的操作,比如克隆……当你直接访问一个字段时,你会绕过这些。这打破了访问者的目标。
【解答3】:

我不认为这是不好的做法,而是语言的一个特点。它不仅允许您以自己的方式测试 equals,而且在创建对象的原型模式中也很有用。

【问题讨论】:

    【解答4】:

    这很好,完全正常。认为 this 可以摆弄 other 的私有字段有点奇怪,但没关系,因为就某些第三方而言,不可能发生任何不好的事情能够弄脏 Odp 对象的内部结构。 Odp 类的任何方法都可以修改任何 Odp 对象的任何私有成员,甚至是非 this 对象,但这很好,因为任何这样的方法显然可以信任!

    【问题讨论】:

      【解答5】:

      这是重复的

      Why can I access my private variables of the "other" object directly, in my equals(Object o) method

      该类的任何实例都可以访问私有数据,即使 A 类的一个实例正在访问 A 的另一个实例的私有成员。重要的是要记住访问修饰符(私有、受保护、公有)正在控制类访问,而不是实例访问

      【问题讨论】:

        【解答6】:

        对实体类使用私有成员可能会导致代理类工作不正确。 想象一下休眠通过惰性查询创建类。如果检查成员变量,则返回 null。 但是如果你调用 get() ,它会从数据库中获取数据并初始化字段。

        【问题讨论】: