隐藏jar文件中的类

是否真的不可能在jar文件中隐藏某些类?

我希望不允许直接实例化类以使其更灵活。 这个jar子里只能看到工厂(或立面)。

除了创建两个项目之外,还有其他方法可以解决这个问题吗? (两个项目:第一个包含类(实现),另一个引用第一个并包含工厂;后面只引用第二个)

如果您的公共工厂方法尝试返回“隐藏”的内容,我认为您将遇到编译器故障或警告。

不,如果不重新实现自己的ClassLoader或使用OSGi或类似的东西,你就无法隐藏公共类。

你可以做的是将接口api与实现分开,例如,有一个项目只包含接口,另一个项目包含实现。 但是,您仍然无法隐藏实现类。

我理解你不是要隐藏实际的课程,只是防止他们在工厂外面建造。 我认为通过在类构造函数中使用包私有(默认)可见性可以很容易地实现这一点。 唯一的限制是您需要将类和工厂放在同一个包中,因此在大中型代码库中,事情可能会变得不必要地复杂化。

如果我正确理解您的问题,您希望确保库的用户被迫使用您的工厂来实例化其对象,而不是使用构造函数本身。

我认为它有两种可能性,其中一种是愚蠢但可用于少数特定情况,另一种是最实用且最常用的方式。

  1. 您可以将所有类放入工厂的私有内部类中。 如果每个class级有一个工厂,这将有效,但如果您通过一个工厂管理了许多不同的类,那么这个工作很难实现。
  2. 您可以使用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() 

虽然你很难做到:-)使用系统属性,你可以控制正在加载的实际实现。 对我来说,这种方法在许多情况下都很好。

我希望我能正确理解你的问题;)

干杯!