Java中的非公共顶级类

在Java中创建顶级类非公共的原因是什么?

假设我们有Foo.java ,可能会有

 class Foo { } 

要么

 public class Foo { } 

我知道前一个例子会有一些类 – 可见性问题(可能从其他包中看不到)。 但无论如何,有没有任何理由为什么有人可能想要像第一个代码示例那样做?

UPD:我在前一个解决方案中看到了什么缺点:没有人关心它non-public 。 稍后可以通过同一个包中的其他public类简单地扩展该类,然后,类的非公共部分可能会为您带来可见性/访问问题。

这是一个例子。 没有人需要知道我们的ConcreteDocument的存在。

DocumentIF.java

 public interface DocumentIF { } 

ConcreteDocument.java

 class ConcreteDocument implements DocumentIF { } 

DocumentFactory.java

 public class DocumentFactory { public DocumentIF createDocument() { return new ConcreteDocument(); } } 

通常,您将类包设为私有,因为您不希望在包外使用该类。 当顶级类不是公共类时,它对包是私有的。

假设您有一个包含许多类的包,这些类必须相互传递相同类型的数据。 但是这个数据结构是一个实现细节,因此您不希望它被用户代码使用。 使传输类包保持私有可以维护这种包级别封装。

我知道前一个例子会有一些类 – 可见性问题(可能从其他包中看不到)。

在我看来,如果你想把这个类私有保存到那个包中,那么我就有足够的理由使用它。


刚注意到另一种用途! 看起来每个代码文件只能有一个公共顶级类,但是任何数量的非公共顶级类。 尚未亲自validation,但如果是真的,那么可以非常有用,可以防止项目文件夹混乱,并将具有相关function的类分组到包外。

没有publicprotected修饰符的类只能在它们所在的包中可见。 如果您考虑组件接口 ,则有理由省略public修饰符。 假设您有一个publicMyCompontent ,它在内部使用其他类,但不想将它们发布到外部世界(组件的用户),而忽略可见性修饰符是有意义的。

将类的可见性保持在最低要求是一种很好的设计。 我能想到的原因:

  1. 该类可以在将来轻松更改,而不会导致外部包中断,因为外部包无法访问该类。 在这方面,通过使一个类成为私有内部类来开始一个类可能更好。
  2. 包可见的类不能通过外部包中的类进行扩展。 这再次使这个类更容易更改而不会导致外部包中的重大更改。 如果不打算扩展这个课程,那么最终做到这一点会更好。
  3. 公共可见类成为库的导出API的一部分。 如果您是图书馆设计师,最好保持导出的API尽可能小,因为您不希望将您的消费者与不必要的类/详细信息混淆。 在这种情况下,第1项将再次保持良好状态。

Josh Bloch的“Effective Java”一书是Idiomatic Java代码和设计的绝佳参考。