Java保护的领域vs公共获得者

什么是更好的做法,为什么:通过私人领域的受保护领域或公共获得者访问基类variables。

(吸气器不pipe公开)

无论如何,如果要有一个公共的获取者,为什么你要把这个领域本身暴露得比绝对必要的更广泛呢? 这意味着它可以立即由子类写入(除非是最后的开头)。

我个人喜欢所有的领域都是私有的:它提供了一个更清晰的API和实现之间的分离。 我认为超类和子类之间的关系类似于调用者和被调用者之间的关系 – 对底层实现的更改不应该破坏子类,而应该比打破​​调用者更多。 字段的名称是不应该影响其他类的实现细节。

无可否认,我的看法偶尔会被视为有点极端…

你应该总是对一个类的公共API进行编程,也就是使用公共方法。

原因很简单。 将来的某一天,您或其他人可能想要更改实施。 这应该总是可能的。 如果你依赖实例variables,你可以限制自己。

另外,访问variables时,您无法控制该variables是否为只读,也不能在此variables更改时添加检查。

如果你使用setter / getters,你可以随时添加validation,稍后检查等。 你也可以只提供一个getter来使variables只读。

直接字段访问不是首选。 使用publicprotected制定者和获得者。

getter不必public – 如果你想隐藏“outsiders”的数据,但是把数据提交给子类,使用protected

Sun的一些关于控制访问字段的build议在这里。 请注意,将一个字段保护也暴露给包,而不仅仅是子类。 一般来说,正如上面的链接所述,除非有充分理由不这样做,否则字段应该是私人的。

有效的Java第二版说

项目13:尽量减lessclass级和成员的可达性

经验法则很简单:使每个class级或成员尽可能不可访问。 换句话说,使用与您正在编写的软件的正常运行一致的最低可能访问级别。

所以如果你不确定为什么你需要一个受保护的类成员(即你不需要这个字段可以被同一个包中的子类或类访问),那么就声明它是私有的。 如果你想从课堂以外的地方设置,那就做一个公开的制定者。

但是,如果你的成员是最终的,那么在某些情况下使它成为保护可能是没有问题的(即它不会显示敏感信息)。

我想提到的一个潜在的安全问题是,如果你有一个声明为protected final(甚至是public final)的数组,数组引用是final(不能被修改),但是数组中的对象不是最终的(入侵者可能更改数组内容)。


如果你知道c ++,你可能知道这一点

const int * someMember

不同于

int * const someMember

后者就像java中的最后一个数组。


上述安全漏洞的修复方法是返回数组的深层副本或将其作为只读列表返回。

一般来说,你应该使用Sun的build议。 有一个很大的例外:如果你是Android的编程。

原因是性能。 对于每个虚拟方法调用,使用查找表将方法路由到其对象都会涉及开销。 访问本地variables时不涉及这个开销。

这里有一些链接,更深入地解释了这一点:

http://developer.android.com/training/articles/perf-tips.html#GettersSetters

http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/

知道你想要完成什么是很重要的:

  1. 客户代码可以使用公共接口访问该字段的值。
  2. 该字段是为了被子类使用。

在普通的Java中,getters和setter完成了这两个任务。 但Android是不同的。 如果你正在做#1,那么你应该使用公共的getters和setter。 如果你正在做#2,那么你应该使用受保护的领域。 如果你正在做这两个,使用两个。

从子类访问受保护的字段是inheritance违反封装的一种方式。 使用公共API更好的是这个原因。