使用Java访问修饰符的重点是什么?

时间:2017-04-15 02:28:11

标签: java javabeans access-modifiers

我已经使用Java很长一段时间了。我知道四种类型的Java访问修饰符和我在实际应用程序中使用它们的经验。

但是,我对访问修饰符有疑问:使用不同访问修饰符的重点是什么?

换句话说,在Java语言设计中使用访问修饰符背后的原因是什么。

是否只是为了阻止其他开发人员意外地访问某些类/属性 ?或者,是因为我们想以某种方式显示"意图"应用程序中类/属性的使用/范围?

我看到许多经验丰富的开发人员处理访问修饰符,并不是因为他们有充分的理由使用它们,而主要是因为语言具有这样的功能并且它是最佳实践。他们主要通过"约定来选择不同的访问修饰符。他们陷入了他们的脑海。

我认为现在很多顾问和专家都不习惯使用访问修饰符,因为他们从不问自己"如何不使用它们"?不要误解我的意思。我并不是说它们没用,我们不应该使用它们。我只想问它是否主要用于改进开发人员的编码惯例。还有许多其他编程语言不支持访问修饰符,但这并不会使它们成为糟糕的语言,它们仍然可以在企业应用程序中使用。

如果您不希望其他课程弄乱他们,我应该尽可能地将类和属性声明为 private

我的一位同事之前给了我这个解释 - "如果我们想将我们的图书馆分享给第三方,我们不希望他们访问某些类/属性。我们希望保密这些类/属性。 "在我看来,我想,"真的吗?这是真的吗?我想你或我,其中一个人的想法非常错误。"

我们说我已经下载了一个开源库,并且 IF 我真的想要访问一些私有类/属性,我可以进入库代码并更改它们访问修饰符,对吗?即使我不想/不能触摸代码,我也可以在运行时使用反射来更改访问修饰符。我知道它是hackish,但那就是我想要的。

我也听过有人说它有数据封装......但我只是想 - Java类已经设计好了这样的封装功能,我不需要访问修改器要做到这一点。

有时,当我阅读第三方库的API文档时,我会看到有关私有类的页面。如果原始开发者选择使用私有访问修饰符,那么我猜他/她有意让这些类远离我们,对吗?这些类可能是为后台逻辑而设计的,不需要向我们公开。那么为什么要在私有类上使用API​​文档呢?

=====

与Java访问修饰符相关的另一件事我不了解,是Java Bean的设计。为什么我们将Bean中的所有字段保密,然后通过公共getter和setter访问它们?为什么我不应该只有公共领域?有时候写入/生成和管理所有这些getter / setter是浪费时间和容易出错的。例如,下面两者之间的区别是什么?

myBean.setX("foo");
String bar = myBean.getX();

相比
myBean.x = "foo";
String bar = myBean.x;

我的同事告诉我,使用吸气剂和固定剂更安全,可以防止任何意外进入。我只是不知道合理的开发人员会如何意外地访问它们。

我之前已阅读过一些书籍,建议您可以在getter和setter中添加逻辑代码和其他数据修改代码,因此当访问getter / setter时,它不仅仅是字段访问。但是,我真的相信这是一种不好的做法。 Java Bean的重点是数据封装。逻辑应该在其他地方完成,而不是在Java Bean内部,特别是在setter和getter中。

4 个答案:

答案 0 :(得分:3)

  

是否只是为了防止其他开发人员意外访问某些类/属性?或者,是因为我们想以某种方式显示"意图"应用程序中类/属性的使用/范围?

基本上......这两件事。

你的同事说:

  

如果我们想将图书馆分享给第三方,我们不希望他们访问某些类/属性。我们希望保密这些类/属性。

你是对的。这不是原因。由于各种原因,private修饰符无法用于此目的。

如果你想保留部分代码/国家的秘密:1)不要共享源代码,2)混淆编译的代码,3)如果你真的关心它,不要分享代码完全 ...因为即使是混淆的代码也可以进行逆向工程,并且需要付出足够的努力。

您的其余问题似乎是您对访问修饰符的意见陈述,我不会回应。 (这是一个Q& A网站。如果你想开始讨论,这是错误的地方!)

答案 1 :(得分:1)

一个词:封装。如果你想驾驶汽车,你不需要知道发动机工作原理的细节,你只需要知道如何使用它。事实上,绝大多数司机对汽车发动机的了解相对较少。

当您使用库时,您更关心如何使用它而不是实现细节。事实上,这是面向对象开发的重点之一。

我不同意你的同事所说的关于保密的内容。你无论如何都可以通过反思获得有关私人方法的信息,所以如果其他人有动力去访问它,你就不能保守秘密。

所做的事情是静态地阻止你在没有做出重大努力的情况下调用你不应该这样做的方法。

通过类比,我无法绕过方向盘和点火装置,并且直接作用于我的汽车发动机,它&#&# 39,我必须不顾一切地去做。该界面可以防止我意外地对发动机采取可能对其有害的操作。

关于文档问题,如果API的公共文档中包含私有方法的详细信息,那么它就是错误的文档。这些信息并不属于面向公众的文档,简单明了。永远。完全没有。出于任何原因。将这些细节包括在面向公众的文件中,将被污染的灵魂召唤到生活的领域。

答案 2 :(得分:1)

尽管有明显的拖鞋,我还是会回答。程序员在软件创建中做出的每一个选择都是锁定代码以执行它应该执行的操作,以及其他任何内容。 (如果那不是你正在做的事情,你不是一个程序员,你只是一个程序员。)"最佳实践"被称为有理由;在实践中,他们是实现这一目标的最佳人选。

公共接口(不是Java关键字,CS概念)和私有实现的实践最适合保持代码无错并且稳定有用。当类型的契约清晰,一致且持久时,该类型比例如与实现细节有过多耦合时更有用且成本更低。

例如,HashMap的公开合约以interface(此次为关键字)Map表示。界面中没有任何内容揭示了如何存储哈希冲突。最近,如果条件允许,实施从链表变为明智地使用红黑树。如果链接列表已公开,则该更改将破坏使用HashMap的每个程序。因为冲突管理是封装的,而不是破坏,所有这些程序的性能都有了很小的改进。

我强烈建议您研究面向对象的编程,以理解封装,Demeter法则,接口编码以及实际上最佳的所有其他最佳实践等概念。

答案 3 :(得分:0)

公共字段倾向于将您链接到特定的实现,并限制您更改代码的灵活性。