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