我想要一个只能访问API包的jar文件。所有其他包(包含实现)都不会被另一个jar(也不是任何其他类)访问。
有可能吗?
如果是,怎么样?
答案 0 :(得分:4)
如果您有不应使用的类,请将它们放入名为" internal"的子包中。虽然这并不妨碍其他人使用这些课程,但强烈表明他们不应该这样做。
示例:
my.library.Stuff
my.library.StuffFactory
my.library.internal.StuffImpl
my.library.internal.MoreStuff
my.library.internal.xml.DataStuff
虽然这不是一个实际的解决方案,但我认为这是一种最佳做法。
答案 1 :(得分:3)
目前为Java 8(2012?)安排的是JSR 294。这个JSR将更好的模块化语言结构引入Java。
今天,可以将实现划分为多个包。这种实现的子部分需要彼此更紧密地耦合,而不是与周围的软件环境相互耦合。今天,设计师被迫将实施的其他子部分所需的程序元素声明为公共部分 - 从而使它们在全球范围内可访问,这显然不是最理想的。
或者,整个实现可以放在一个包中。这解决了上面的问题,但是不实用,并且将所有子部件的所有内部部件相互暴露。
设想的语言变化将解决这些问题。特别是,我们希望在语言级别引入一个新的模块概念( superpackages ),其中现有的公共访问控制仅适用于语言级模块,并且从模块外部访问API将仅限于模块明确导出的API。
现在我相信专家组仍在讨论这个概念的细节。但我相信你可以做的一件事就是(来源:Super Packages in Java 7.0):
superpackage com.myorg.myApp.model
{
member package com.myorg.myApp.model.swing;
member package com.myorg.myApp.model.html;
export com.myorg.myApp.model.swing.SEmployee;
export com.myorg.myApp.model.swing.SDepartment;
export package com.myorg.myApp.model.html;
}
换句话说,对于给定的“超级包装”,您可以独立于public
等可见性关键字来定义什么是导出和不导出。
答案 2 :(得分:2)
除非你使用的是我认为你不是的OSGI,否则这在Java 6中是不可能实现的。 我通常最终要做的是隐藏类是为了实现使用包友好类 - 但是如果你的实现类确实存在于一个单独的包中,你可能仍然需要公开一些类。
示例:
package com.example;
public class Service { }
假设API类使用ServiceImpl
作为其实现
现在,如果ServiceImpl
位于同一个包中,您可能会删除它的公共类修饰符,并且无法在包外部访问它...
如果它位于不同的包裹(您的情况),则需要公开:
package com.example.impl;
public class ServiceImpl { }
但是同一个包中的所有实现细节(它使用的相关类)都不需要公开!
答案 3 :(得分:1)
在“普通”的java应用程序中,这是不可能的。虽然在OSGi环境中,您可以定义捆绑包(稍微修改过的jar文件)向其他捆绑包公开哪些包,哪些包是私有的(在捆绑包外部不可见)。
答案 4 :(得分:0)
为什么不简单地创建一个带有API类的jar和一个带有依赖于API的实现的分离jar。这样,您可以在不分发实现的情况下分发API类。
KR。
答案 5 :(得分:0)
我可以看到你想要这样做的原因。当我尝试使用某人的图书馆时,它一直困扰着我。有很多课程,我不知道从哪里开始。
据我所知,大多数图书馆都没有这样的图书馆试图隐藏不相关的类。虽然这不是一个确凿的证据,但它必然意味着没有办法做到这一点。通常,他们将api和实现发布到分离的jar文件中。
但是,如果您通过OSGi框架运行应用程序,则可以捆绑您的jar文件,使OSGi框架只能看到您想要的API类。但是使用OSGi可能有点工作。
答案 6 :(得分:0)
根据您的构建工具首选项,您可以添加ant-task或maven-jar-plugin配置来包装所需的组件。
答案 7 :(得分:0)
另一种解决方案是在实现类中设置默认访问修饰符,并将它们放在与接口相同的包中。虽然它有点脏。