目前,我所做的是创建一个包含几个静态最终布尔属性的类,例如以下示例:
public class Preprocessor { public static final boolean FULLACCESS = false; }
然后我以下列方式使用:
public ClassName getClassName() { if(Preprocessor.FULLACCESS) { return this; } else { return this.DeepCopy(); } }
到目前为止这么好,这解决了我的问题(上面的例子是微不足道的,但我在其他情况下使用它是有用的).我的问题是,有没有办法放置一个整个方法的条件,所以方法本身将不可用给定正确的“预处理器”变量?例如,我想要使一个特定的构造函数仅适用于“完全访问”的包,如下所示:
public ClassName() { // do things } if(FULLACCESS) { public ClassName(ClassName thing) { // copy contents from thing to the object being created } }
再次,我知道Java作为一种语言的局限性(或设计决策),并且我知道在大多数情况下这是不必要的.实际上,我已经考虑过简单地创建这些“额外的”方法,并将它们的整个代码放在一个有条件的内容中,同时抛出一个异常,如果条件是不活动的,但这是一个非常粗略的解决方案似乎没有帮助给我的程序员,当我把这些图书馆提供给他们.
非常感谢您的任何帮助.
编辑:
为了补充这个问题,我试图这样做的原因是,通过使用异常作为解决方案,IDE实际上不会将方法显示为“可用”.然而,再次,这可能只是我对Java无知的情况.
我想要这样做的原因主要是因为我可以有多个公共接口可用,比如说,一个限制性的方法中的控制是更严格的,另外一个允许的,允许直接的属性变化.但是,我也希望能够主动从.class中删除部分代码,例如,在某些变体不可用的产品线开发方法中.
EDIT2:
此外,重要的是要注意,我也将有条件地生成文档.因此,每个编译版本的包将有自己的文档,仅包含实际可用的文档.
解决方法
我建议您使用Java接口来实现,这些接口只暴露出你所期望的API.当您需要限制较少的API合同时,扩展接口或创建现有界面的单独实现,以获得所需的内容.
public interface A { void f(); }
以上是您的一般API.现在你想要一些特殊的额外的方法来测试A或调试它或操纵它或任何…
public interface B extends A { void specialAccess(); }
此外,Java现在支持接口的默认方法实现,这可能对您有用,具体取决于实现API的方式.他们采取以下形式…
public interface A { List getList(); // this is still only an interface,but you have a default impl. here default void add(Object o) { getList().add(o); } }
您可以在Oracle’s page about it here上阅读有关默认方法的更多信息.
在您的API中,您的普遍分发可能包括A和完全省略B,并省略提供特殊访问权限的任何实现;那么您可以为您提到的API的特殊访问版本包含B和特殊实现.这将允许普通的旧Java对象,除了一个额外的接口,也可能是一个额外的实现,代码没有什么不同.定制部分将仅在您的图书馆包装中.如果你想给某人一个“非特殊”的低访问版本,请给他们一个不包括B的jar,不包括任何可能的BI实现,可能通过单独的构建脚本.
我使用Netbeans作为我的Java工作,我喜欢让它使用它自动生成的默认构建脚本.所以如果我这样做,我在Netbeans做的,我可能会创建两个项目,一个用于基本API,一个用于特殊访问API,我将使特殊访问依赖于基础项目.那会让我有两个罐子,而不是一个罐子,但我会很好的;如果两个罐子让我足够麻烦,我将会经历上面提到的特殊访问版本的构建脚本的额外步骤.
一些直接来自Java的例子
Swing有这种模式的例子.请注意,GUI组件有一个void paint(Graphics g).图形给你一定的功能.一般来说,这个g实际上是一个Graphics2D,所以你可以这样对待,如果你愿意的话.
void paint(Graphics g) { Graphics2d g2d = Graphics2d.class.cast(g); }
另一个例子是使用Swing组件模型.如果使用JList或JComboBox在GUI中显示对象列表,则如果要随时间更改该列表,则可能不使用默认模型.相反,您创建一个具有添加功能的新模型并注入它.
JList list = new JList(); DefaultListModel model = new DefaultListModel(); list.setModel(model);