如何修剪Java程序

| 让我从我想做的事情开始,然后提出一些我有的问题。 我想开发一个通用的Java程序,它是许多程序的超集(我们称它们为程序变体)。特别地,通用程序具有仅由一个或多个程序变体(但不是全部)使用的方法。给定特定的配置,我想删除不必要的方法,而只保留一个程序变体的最小方法集。 例如,我有如下通用程序:
public class GeneralProgram {

    // this method is common for all variants
    public void method1() {};

    // this method is specific to variant 1
    public void method2() {};

    // this method is specific to variant 2
    public void method3() {};
}
然后,根据变式1的配置修剪程序后,结果是
public class GeneralProgram {

    // this method is common for all variants
    public void method1() {};

    // this method is specific to variant 1
    public void method2() {};
}
所产生的类名称是否与原始名称相同并不重要。我只想删节课的内容。 所以,这是我的问题: 除了低级文本处理之外,您是否有其他想法? 我知道我可以在运行时使用AspectJ禁用/启用特定方法,但是我真正想做的是在部署程序之前执行此任务。 Java是否有为此目的的任何技术?     
已邀请:
        在我看来,这里的正确解决方案是使用一些面向对象的程序并对程序进行分层: base.jar包含:
package foo.base;
class GeneralProgram {
   public void method1(){ }
}
var1.jar包含:
package foo.var1;
import foo.base.GeneralProgram;
class GeneralProgramVar1 extends GeneralProgram {
   public void method2(){ }
}
var2.jar包含:
package foo.var2;
import foo.base.GeneralProgram;
class GeneralProgramVar2 extends GeneralProgram {
   public void method3(){ }
}
一些部署将同时具有base.jar和var1.jar,其他部署将具有base.jar和var2.jar。您将不得不弄乱类路径来解决依赖关系。 如果您可以很好地分离变体,以便真正存在未使用的函数,则可以使用ProGuard之类的压缩实用程序从类中删除未使用的方法。但是,您可能会发现,获得ProGuard好处所需的工作与我上面建议的结构相同。     
        @Mark Elliot的答案为您提供了“正确的方法”。 有很多原因导致您的方式通常不是一个好主意,尤其是对于Java应用程序: Java不支持此功能。具体来说,它不支持条件编译。 尽管有时会使用源代码预处理器,但主流Java工具链不支持它们。 (与(假设的?)在字节码级别上运行的工具相同……尽管这似乎并不是您所要讨论的。) 使用条件编译变体,对一个变体进行的更改更容易破坏另一个变体。 (相比之下,好的O-O设计会将变体特定的代码隔离到不影响其他变体行为的特定类。) 具有泛滥的条件编译的代码库更难理解。 条件编译变体使测试更加复杂。基本上,您必须将每个变体视为必须单独测试的单独应用程序。这使编写测试变得更加复杂,而运行测试则变得更加昂贵。 (由于依赖条件编译的代码库的脆弱性,测试变体非常重要;请参见前文。) 由于工具问题,测试覆盖率分析变得更加困难/需要更多的变体。见前面。 OP在评论中写道:   因此,如果我为特定变体部署不必要的资源(例如方法,特定于其他变体的类),这是无效的。 “无效”是什么意思? 在大多数情况下,代码库包含某些用例或某些平台上未使用的功能根本没有关系。 Java应用程序使用大量内存,并且代码大小通常不是造成此问题的主要原因。简而言之,在大多数情况下,部署不会使用的代码是“有效的”:它可以完成工作,而开销却无关紧要。 如果您拥有JAR文件大小或代码内存使用量确实很重要的异常应用程序之一(而不仅仅是一个假设的问题),那么您仍然不需要诉诸条件编译或字节码黑客。 如果JAR文件大小是关键问题,则可以使用某些工具来删除该工具确定不会使用的类和方法;例如假定应用程序是从指定的“ 5”方法启动的。 如果内存使用是关键问题,则可以对代码进行结构化,使其使用动态加载来加载变量,平台甚至特定于用例的类。     

要回复问题请先登录注册