假设我有这个 Java 应用程序:
package com.site;
public class MyAppBase {}
package com.site.free;
import com.site.MyAppBase;
public class MyApp extends MyAppBase {}
package com.site.pro;
import com.site.MyAppBase;
public class MyApp extends MyAppBase {}
package com.site;
public class Edition
{
public static final int FREE = 1;
public static final int PRO = 2;
private static final int EDITION = PRO;
public static boolean is(final int edition)
{
return (EDITION == edition);
}
}
package com.site;
public class EditionFactory
{
public static MyAppBase get_app()
{
MyAppBase ret = null;
if (Edition.is(Edition.FREE))
ret = new com.site.free.MyApp();
else if (Edition.is(Edition.PRO))
ret = new com.site.pro.MyApp();
return ret;
}
}
现在,我试图摆脱非选定版本(在本例中它是免费的)的 ProGuard 配置的任何组合都不起作用。
我所说的“摆脱”是指让实际的类消失(以及从调用代码中消失)。
换句话说,像这样的调用:
final MyAppBase app = EditionFactory.get_app();
.. 经过 ProGuarding 后,目前正在翻译为:
if (a.a(1))
localObject5 = new c(); // <<< FREE
else if (a.a(2))
localObject5 = new d(); // <<< PRO
..虽然我希望它被翻译成这样:
localObject5 = new d(); // <<< PRO only in the code (as set at Edition.EDITION)
底线是 (除此之外,ProGuard 非常棒!),我似乎无法让它“看透”并理解 Edition.is() 是一个返回常量的布尔函数,这使得可以删除一些类。
我尝试过如下配置:
-keep,allowshrinking,allowoptimization public class * extends com.site.MyAppBase
-optimizationpasses 10
..没有任何作用。
另一方面,如果我引用 Edition.EDITION 并内联比较它(即没有任何“代理”函数),Java 编译器(v1.6)会检测到它并删除对未选择的版本/类的整个引用。
这导致 ProGuard 删除/缩小未使用的类,这很棒。
这里唯一的问题是关于维护 - 我很高兴能够继续使用 EditionFactory 风格。