在jar文件中隐藏某些类真的不可能吗?
我不想让类的直接实例化以保持它更灵活。只有工厂(或立面)才能看到这个罐子。
除了创建两个项目之外,还有其他方法可以解决这个问题吗?(两个项目:第一个包含类(实现),另一个引用第一个并包含工厂;稍后将仅引用第二个)
在jar文件中隐藏某些类真的不可能吗?
我不想让类的直接实例化以保持它更灵活。只有工厂(或立面)才能看到这个罐子。
除了创建两个项目之外,还有其他方法可以解决这个问题吗?(两个项目:第一个包含类(实现),另一个引用第一个并包含工厂;稍后将仅引用第二个)
我了解您并不想隐藏实际的类,只是防止它们在工厂类之外构建。我认为通过在类构造函数中使用包私有(默认)可见性可以很容易地实现这一点。唯一的限制是您需要将类和工厂放在同一个包中,因此在大中型代码库中,事情可能会变得不必要地复杂。
如果您的公共工厂方法尝试返回“隐藏”的内容,我认为您将遇到编译器失败或警告。
ClassLoader
不,如果不重新实现您自己的或使用 OSGi 或类似的东西,您就无法隐藏公共类。
您可以做的是将接口 api 从实现中分离出来,例如,有一个只包含接口的项目和另一个包含实现的项目。但是,您仍然无法隐藏实现类。
混淆可以以某种方式帮助您。
使用标准类加载器和普通的旧 jar 文件,这是不可能的。OSGi 有这样一个概念,即仅使某些包对另一个包可见(即公共 api 和内部实现的分离)。
如果您使用的是 eclipse,则可以使用此命令强制执行此类规则
如果当您说“不允许直接实例化类以使其更灵活”时我理解正确,则正确执行的外观模式将处理此问题。
将要隐藏的所有类的构造函数限制在包范围内。将外观类打开到公共范围。
http://mindprod.com/jgloss/packagescope.html
“如果你的类中有一个变量或方法,你不希望你的类的客户直接访问,不要给它一个公共的、受保护的或私有的声明。由于 Java 设计的疏忽,你可以” t 显式声明默认的“包”可访问性。包的其他成员将能够看到它,但从您的包继承的包外的类不会。受保护的可访问性属性提供了更多的可见性。受保护的方法是可见的继承类,甚至不是同一个包的一部分。包范围(默认)方法不是。这是受保护和包范围之间的唯一区别。“
您可以使用自定义类加载器来做这样的魔术,但是:
在这种情况下,我会做一些类似于我们在标准 Java 中看到的事情。例如,您看到javax.xml.stream.XMLInputFactory
但在某处您有com.sun.xml.internal.stream.XMLInputFactoryImpl
。如果你写它是完全可编译的:
new com.sun.xml.internal.stream.XMLInputFactoryImpl()
尽管您几乎不会这样做 :-) 使用系统属性,您可以控制正在加载的实际实现。对我来说,这种方法在许多情况下都很好。
我希望我正确理解了你的问题;)
干杯!