Java 包装和可视性

Java 包装和可视性,java,packages,encapsulation,access-modifiers,class-visibility,Java,Packages,Encapsulation,Access Modifiers,Class Visibility,我正在制作一个SDK,我正在尝试将类分离到不同的包中,这些类使用其他一些共享类。问题是,如果我公开了共享类,那么每个人都可以看到它们,而不仅仅是我的类。什么是使它们只能由我的应用程序访问的正确方法 例如: a包 MyClass1 b包 MyClass2 包c 公共MySharedClass 因为c是公共的,MySharedClass将能够访问它,但问题是它也将对世界可见,我如何防止这种情况发生?在Java中,包都是公共的,您可以保护包中的类。要将类的可见性限制为仅给定包,请在不使用公共可见性修饰

我正在制作一个SDK,我正在尝试将类分离到不同的包中,这些类使用其他一些共享类。问题是,如果我公开了共享类,那么每个人都可以看到它们,而不仅仅是我的类。什么是使它们只能由我的应用程序访问的正确方法

例如:

a包 MyClass1

b包 MyClass2

包c 公共MySharedClass


因为c是公共的,MySharedClass将能够访问它,但问题是它也将对世界可见,我如何防止这种情况发生?

在Java中,包都是公共的,您可以保护包中的类。要将类的可见性限制为仅给定包,请在不使用公共可见性修饰符的情况下如下声明:

class MyClass {
    // ...
}

这样,只有与MyClass位于同一个包中的类才能看到它。

如果该类由来自两个不同包的类共享,则很可能表明这两个类应与共享类位于同一个包中,它不是公共的,因此只能由相同包的类使用


如果它真的不是一个选项,只需适当地记录共享类,以表明它不应该在SDK内部代码之外使用,它可能会在将来的版本中发生更改,将包命名为internal或诸如此类的东西,使其更加清晰。

创建一个记录为内部包的包,不供客户端使用

Java中没有办法使类仅对某些包公开:它要么对所有人公开,要么只在声明的包中公开包私有


我认为有人建议使用模块来更好地控制类的可见性,但我们至少要等到Java 8。

如果您的类只能在同一个包中访问,则可以使用受保护的修饰符。否则就没有可能

非常重要:

共享类可以由一组通常可访问的接口定义。实际实现应该通过类加载器显式加载。之后,只需应用Java安全管理机制来控制对实现类的访问。任何人都可以看到接口,对实际实现的访问将仅限于您的SDK

每个web/app服务器都需要执行上述各种操作。您认为Tomcat是如何阻止您访问其他应用程序的公共类的


编辑:上面的注释是一个运行时机制。还有静态编译后方法。例如,APT在这里可能有效。当然,我不是要在OP中对您的软件包进行重组,而是要解决如何确保使用通用方法。但这些都有点“黑客”——类加载的运行时机制是规范的,严格来说,我更正确。

但通过这样做,我必须将使用该类的所有类移动到同一个包中。这就是我想要避免的,如果可能的话。是的。以这样一种方式构造项目:所有内部非公共类在一系列包中分组在一起,公共类在其他包中。您可以通过公共包中的公共外观公开内部类的功能。如果需要,您甚至可以在之后混淆内部类。您的客户仍然可以看到,但不再真正可用。另外,只为您的非内部类生成javadoc,这使客户很明显不依赖您的内部类可能重复:+1请参见,Java 8模块==Jigsaw