除了更好的可读性之外,还有其他任何访问修饰符吗?

时间:2012-03-12 13:03:59

标签: java access-modifiers

我的意思是,如果我在Java中声明任何访问修饰符,那么修饰符可以被规避(包私有和受保护 - 包注入;任何 - 反射)。我知道声明这些东西有助于理解和组织代码,但除此之外,是否有任何技术原因或固有的Java功能?

谢谢你们的精彩回应。我很遗憾我只能将一个答案标记为已接受。

6 个答案:

答案 0 :(得分:5)

是的,他们可以被规避。你指出的依赖注入的例子实际上是一个有用的规避案例。注入私有成员不会污染接口,并且在运行时不容易混淆。然而,要想看到核心利益,请将其视为一个软件架构师,主持一个非常懒惰或缺乏经验的团队。

请记住,精心设计的物体应具有高内聚力和松散耦合。高凝聚力意味着一个对象处理它在语义上要处理的问题,仅此而已。松散耦合意味着对象依赖于接口而不是特定的实现。请记住,这样做的好处是它使您的代码更易于阅读,理解,测试和更改。这降低了成本,并且通常使利益相关者满意。作为一名建筑师,这就是你所关心的。假设的懒惰/缺乏经验的团队只关心立即完成队列中的任何任务,即使牺牲质量和未来的生产力。

访问修饰符显示为对象定义的接口背后的一些意图。通常,如果您编写的代码很好,那么您几乎总是只需要公共和私有修饰符。在极少数情况下,关注点无法轻易/清晰地分成单个内聚对象,还有“受保护”关键字允许从对象进行有限的外部访问,这些对象应该在逻辑上共享相关问题。

表达接口背后的意图的更好但更有趣的方法是design by contract,它使用更强大的接口注释集,以便允许预处理工具强制执行接口规则。

TL; DR:

编译器执行访问修饰符非常棒。编译器为那些本来很乐意降低内聚力和增加代码库耦合以便更快地完成他们的即时任务的人提供了一个相当不便的障碍。

答案 1 :(得分:2)

我会说是的,因为它们可以防止无意中滥用。你真的必须不受限制,你不能盲目这样做。

另外,它们表示内部与外部/ API意图。如果你以用户的身份忽视这一点,那么你就会承认你为未来的问题敞开心扉。

答案 2 :(得分:2)

一个重要的原因(我相信最重要的)是它可以让您更好地推理您的代码。

作为班级的作者,您必须假设您的访问修饰符不会被绕过。这允许您在调用方法之前对对象的状态做出更好的假设。您确切知道将调用private方法的位置以及对象所处的状态。您无法对public方法做出相同的假设。

一个示例可能是private方法可以访问多线程上下文中的某个共享状态,知道它是从另一个持有锁定共享状态的方法调用的,而public方法1}}方法可能需要在访问共享资源之前获取锁。

答案 3 :(得分:1)

  

可以绕过修饰符(包私有和受保护 - 包注入;任何 - 反射)。

如果您使用安全管理器和签名的JAR运行,则这些都不可能。因此,访问修饰符实际上可以用作受控环境中的安全机制。

然而,在绝大多数情况下,他们的目的确实是代码组织(我认为可读性不是正确的词)。

答案 4 :(得分:1)

作为一个不同的答案,我认为在撰写API时,它们很重要,因为它们定义了您与API的消费者签订的公共合同。你可以绕过它们,是的,但它清楚地说明了实际支持的内容。

答案 5 :(得分:0)

私有/受保护的帮助使代码更安全并防止紧密耦合,从而有助于重用,降低维护成本。我可以一整天都去!