隐藏jar文件中的类
是否真的不可能在jar文件中隐藏某些类?
我希望不允许直接实例化类以使其更灵活。 这个jar子里只能看到工厂(或立面)。
除了创建两个项目之外,还有其他方法可以解决这个问题吗? (两个项目:第一个包含类(实现),另一个引用第一个并包含工厂;后面只引用第二个)
如果您的公共工厂方法尝试返回“隐藏”的内容,我认为您将遇到编译器故障或警告。
不,如果不重新实现自己的ClassLoader
或使用OSGi或类似的东西,你就无法隐藏公共类。
你可以做的是将接口api与实现分开,例如,有一个项目只包含接口,另一个项目包含实现。 但是,您仍然无法隐藏实现类。
我理解你不是要隐藏实际的课程,只是防止他们在工厂外面建造。 我认为通过在类构造函数中使用包私有(默认)可见性可以很容易地实现这一点。 唯一的限制是您需要将类和工厂放在同一个包中,因此在大中型代码库中,事情可能会变得不必要地复杂化。
如果我正确理解您的问题,您希望确保库的用户被迫使用您的工厂来实例化其对象,而不是使用构造函数本身。
我认为它有两种可能性,其中一种是愚蠢但可用于少数特定情况,另一种是最实用且最常用的方式。
- 您可以将所有类放入工厂的私有内部类中。 如果每个class级有一个工厂,这将有效,但如果您通过一个工厂管理了许多不同的类,那么这个工作很难实现。
- 您可以使用
protected
访问修饰符来限制对类构造函数的访问。 这是使用工厂模式时的常见做法 。
混淆可以帮助你。
对于标准的类加载器,这是一个普通的旧jar文件,这是不可能的。 OSGi提出了这样一个概念,即只向其他包提供一些包而不是其他包(即公共API和内部实现的分离)。
如果你是usnotf eclipse,你可以用这个来执行这些规则
当你说“不允许直接实例化类以保持其更灵活”时,如果我理解正确的话,正确执行的外观模式将处理这个问题。
将要隐藏的所有类的构造函数限制为打包范围。 将外观类打开到公共范围。
http://mindprod.com/jgloss/packagescope.html
“如果你的class级中有一个变量或方法,你不希望你的class级的客户直接访问,不要给它一个公开的,受保护的或私人的声明。由于Java设计的疏忽,你可以’显式声明默认的“包”可访问性。包的其他成员将能够看到它,但是包inheritance自你的包之外的类不会。受保护的可访问性属性提供稍微更加可见。受保护的方法是可见的inheritance类,甚至不是同一个包的一部分。包范围(默认)方法不是。这是受保护包和包范围之间的唯一区别。
您的问题有两种解决方案,不涉及将所有类保留在同一个包中。
第一种是使用(Practical API Design,Tulach 2008)中描述的Friend Accessor / Friend Package模式。
第二是使用OSGi。 这里有一篇文章解释了OSGi如何实现这一点。
相关问题: 1,2,3和4 。
您可以使用自定义类加载器执行此类魔术,但:
- 正确的分离只能在配备您的类加载器的项目中使用;
- 创造这种装载机的努力是值得的,这真的令人怀疑。
在这种情况下,我会做类似于我们在标准Java中看到的内容。 您可以看到javax.xml.stream.XMLInputFactory
但有一些地方有com.sun.xml.internal.stream.XMLInputFactoryImpl
。 如果你写的话是完全可编辑的:
new com.sun.xml.internal.stream.XMLInputFactoryImpl()
虽然你很难做到:-)使用系统属性,你可以控制正在加载的实际实现。 对我来说,这种方法在许多情况下都很好。
我希望我能正确理解你的问题;)
干杯!