为什么Java中缺少friend指令?

我想知道为什么Java的设计没有C ++中提供的friend指令,以便更好地控制哪些方法和实例变量可以从已定义类的包外部获得。

我没有看到任何实际的原因或任何特定的缺点,它似乎只是一个设计问题,但如果添加到语言中不会产生任何问题。

以下是我头脑中的几个原因:

  • 朋友不是必需的。 这很方便,但不是必需的
  • 朋友支持糟糕的设计。 如果一个class级要求朋友访问另一个class级,那你就错了。 (见上文,方便,不需要)。
  • 朋友打破了封装。 基本上,我所有的私人都属于我,那个人(我的朋友)。

总的来说,我认为这是因为增加了认知复杂性,并且创造了改进的案例数量很少。

我会说在这个时刻生产的极其庞大的java行可以certificatefriend关键字并不是真正的大损失:)。

有关更具体的原因,请参阅@ dwb的答案。

只有一个非常天真和没有经验的程序员会提倡反对朋友。 当然它可能被滥用,但公共数据也是如此,但提供了这种能力。

与流行的观点相反,在许多情况下,尤其是基础设施function,其中朋友访问导致更好的设计,而不是更糟糕的设计。 当一个方法被强制公开时,经常会违反封装,但是我们别无选择,因为Java不支持朋友。

除了前面提到的包可见性之外,Java还提供了内部和匿名类,它们不仅默认情况下是朋友,而且还自动引用包含类。 由于创建这样的辅助类可能是在C ++中使用friend的唯一合理方法,因此Java不需要它,因为它有另一种机制。 迭代器就是一个非常好的例子。

为什么不简单地认为Java要求朋友类共存? 包私有可见性允许来自同一包的每个人访问这些成员。 因此,您不仅限于明确声明的朋友,而且您允许任何(现有的或未来的)朋友改变一些专门为此目的而设计的成员(但不是您的私人内容)。 你仍然可以完全依赖封装。

只是为了添加其他答案:

Java中有默认的包可见性 。 因此,您可以调用相同包邻居中的所有类。 在这种情况下,您可以明确控制您向邻居显示的内容 – 只有具有包可见性的成员。

所以,它不是真正的朋友,但可以是相似的。 是的,这也导致糟糕的设计……

在我看来,某些朋友的function(不一定非常类似于C ++)在Java中的某些情况下会非常有用。 目前我们有包私有/默认访问黑客,允许在同一个包中紧密耦合的类之间进行协作(例如StringStringBuffer ),但这会打开私有实现接口直到整个包。 在包之间我们有邪恶的reflection黑客,这会导致一系列问题。

Java中有一些额外的复杂function。 C ++忽略访问限制,同时解决函数重载(和类似) – 如果程序编译#define private public不应该做任何事情。 Java(主要)丢弃不可访问的成员。 如果需要考虑友谊,那么解决方案就会更加复杂和不那么明显。

在他的回答中完全赞同spaceghost的陈述

与流行的观点相反,在许多情况下,尤其是基础设施function,其中朋友访问导致更好的设计,而不是更糟糕的设计。

我的例子很简单 – 如果A类必须在java中为B类提供一个特殊的“朋友”接口,我们必须将它们放在同一个包中。 没有例外。 在这种情况下,如果A是B的朋友而B是C的朋友,则A必须是C的朋友并不总是如此。 这种“友谊传递性”打破了封装,而不是C ++友谊可能导致的任何问题。

Interesting Posts