【问题标题】:Non-public top level class in JavaJava中的非公共顶级类
【发布时间】:2011-08-09 13:15:06
【问题描述】:

在 Java 中将顶级类设为非公开的原因是什么?

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

class Foo {
}

public class Foo {
}

我知道前一个示例会存在一些类可见性问题(可能从其他包中看不到)。但无论如何,有什么理由可以让某人像第一个代码示例中那样做吗?

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

【问题讨论】:

  • 因为如果没有必要,为什么还要在上面放额外的代码呢~

标签: java


【解决方案1】:

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

DocumentIF.java

public interface DocumentIF {
}

ConcreteDocument.java

class ConcreteDocument implements DocumentIF {
}

DocumentFactory.java

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

【讨论】:

  • 请注意这些类在不同的文件中;-)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    我知道前一个示例会存在一些类可见性问题(可能在其他包中不可见)。

    在我看来,如果您想让该类对那个包保持私有,那么使用它就足够了。


    刚刚注意到另一个用途!似乎每个代码文件只能有一个公共顶级类,但可以有任意数量的非公共顶级类。还没有亲自验证过,但如果属实,这对于防止项目文件夹混乱以及对具有包外不需要的相关功能的类进行分组非常有用。

    【讨论】:

    • 第二点是对的,但是在一个文件中放置多个顶级类是一种不好的做法。想象一下,您决定 Alpha.java 应该有一个公共的 Alpha 类和一个非公共的 Helper 类。然后你的同事(在同一个包中工作)决定 Beta.java 应该有一个公共的 Beta 类和一个非公共的 Helper 类。碰撞!如果(1)你们都将 Helper 类嵌套在各自的顶级类中(最好),则可以避免这种冲突;或者 (2) 你们都将 Helper 类放在自己的编译单元中(第二个开发人员会马上看到问题)。
    • @emory:这就是为什么我更喜欢 Python 和类似语言处理事情的方式,其中每个文件本身都是一个具有自己的模块级命名空间的模块,这样的冲突通常不会发生.非常喜欢您的嵌套解决方案。 ...实际上,我想您可以通过仅使用一个顶级类作为要合并的类的包装器来模拟该功能,而无需任何实际功能本身,尽管我认为这有点违背良好的编程习惯在 Java 中也是如此。
    • @emory 如果这是最严重的问题,那么我认为这不是什么大问题。开发人员将在他们第一次编译时收到通知,这将是一个简单的修复。当然,即使是 IDE 也会在此之前通知他们。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      1. 将来可以轻松更改该类,而不会导致外部包损坏,因为外部包无权访问该类。在这方面,通过将一个类设为私有内部类来开始一个类可能会更好。
      2. 包可见的类不能被外部包中的类扩展。这再次使此类更改更容易,而不会导致外部包的破坏性更改。如果这个类不打算被扩展,那么做这个最终会更好。
      3. 公共可见类成为库的导出 API 的一部分。如果您是库设计者,最好将导出的 API 保持尽可能小,因为您不希望将您的消费者与不必要的类/细节混淆。在这种情况下,第 1 项仍然适用。

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

      【讨论】:

        猜你喜欢
        • 2011-01-10
        • 1970-01-01
        • 2020-03-18
        • 2011-08-24
        • 2013-04-09
        • 2019-06-24
        • 2011-02-14
        • 2011-01-30
        相关资源
        最近更新 更多