java ProGuard 删除(收缩)未使用的类

标签 java proguard

假设我有这个 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() 是一个返回常量的 boolean 函数,这使得可以删除一些类。

我试过如下配置:

-keep,allowshrinking,allowoptimization public class * extends com.site.MyAppBase
-optimizationpasses 10

.. 什么都没用。

另一方面,如果我引用 Edition.EDITION 并比较它内联(即没有任何“代理”函数),Java 编译器 (v1.6) 会检测到它并删除整个引用未选择的版本/类别。
这导致 ProGuard 删除/缩小未使用的类,这很棒。

这里唯一的问题是关于维护——我很乐意继续使用 EditionFactory 样式。

最佳答案

未执行优化是因为 ProGuard 决定不内联方法 Edition#is,因此它无法简化生成的指令系列。该方法没有内联,因为它不是很短,而且它也被调用了不止一次。您可以使用 ProGuard 的这个未记录的 JVM 选项解决第一个标准:

-Dmaximum.inlined.code.length=16

或者,您可以解决第二个标准,方法是确保该方法只被调用一次:

return Edition.is(Edition.FREE) ?
    new com.site.free.MyApp() :
    new com.site.pro.MyApp();

或者,您可以创建短函数 isFree() 和 isPro(),因为它们会返回内联常量。

如果您希望进行某些特定的优化,最好检查已处理的代码,因为它们通常受到复杂的约束。

很高兴听到您喜欢 ProGuard。

关于java ProGuard 删除(收缩)未使用的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7061124/

相关文章:

java - 为什么 Hibernate 会重复对象,尽管数据库表不包含重复行?

java-me - 使用 Bouncy CasSTLe 库会导致输出 .jar 文件大小大幅增加

java - Scala 可运行 JAR 的 ProGuard 进程

java - 我正在使用 proguard 插件的 -repackageclasses 'my.pdt.z' 选项,但混淆的文件仍然存在于其他文件夹中

java - 使用自定义请求对象时带有可选参数的 Spring @RequestMapping

单击 1 次后 JavaFX 刷新按钮消失

java - 无法找出下面代码中的运行时错误

java - 如何获取所有可能的函数异常的列表

android - 生成 Proguarded 签名 APK 问题?

sbt - ProGuard 使用 sbt-proguard 表示不支持的类版本号 [52.0](最大 51.0,Java 1.7)