1

我想知道您是否可以使用编译器的技巧为应用程序的免费和付费版本包含不同的功能。例如:

public static final boolean paid = false;

if (paid){
    runPaidMethod();
}
else {
    runFreeMethod();
}

编译器会查看它并说它不需要 if 语句的第一个分支,因此它不会编译它。此外,它应该查看程序并查看runPaidMethod()不再从任何地方引用的程序并将其删除。

因此问题是:只有这个标志是否可行,免费编译一次,交换标志然后再次编译付费?

4

2 回答 2

2

使用最终布尔变量很好,因为 Java 编译器足够聪明,可以看到您的条件始终为假。如果您反编译已编译的类(您可以尝试使用javap -c命令),您将看到您的代码:

public static final boolean paid = false;

if (paid) {
    runPaidMethod();
}
else {
    runFreeMethod();
}

将被编译为一次调用:

runFreeMethod();

编译器会删除任何无法访问的代码,因此没有人能够对您的应用程序进行逆向工程。但是要注意,你必须声明runPaidMethod()为私有方法,否则它的内容仍然会出现在编译的类中。

但是从维护的角度来看,使用库项目来处理多个应用程序版本仍然更好。

于 2012-06-23T18:05:55.903 回答
1

您试图表达的概念称为条件编译。在像 C 或 C++ 这样的语言中,您可以通过组合预处理器指令和编译器标志来完成此操作。一个相当粗略的例子:

#ifdef PAID
    runPaidMethod();
#else
    runFreeMethod();
#endif

好,坏或无所谓,这种条件编译在Java中是不存在的。但这并不是说您尝试做的事情无法完成,您只需要以更加面向对象的方式思考。实现您所寻求的一种方法是将您的主要服务提供者定义为接口,并为付费和免费版本提供实现。就像是:

public interface UsefulService {
    public void someMethod();
    public void otherMethod();
}

public class BaseUsefulService {
   // Common functionality here
   public void otherMethod() {
   }
}

public class FreeUsefulService {
    public void someMethod() {
    }
}

public class PaidUsefulService {
   public void someMethod() {
   }
}

通过这种分解,您实际上可以将应用程序的付费版本构建到一个完全独立的应用程序中(通过将其所有服务提供商放在一个单独的项目中)。

于 2012-06-23T17:52:29.910 回答