【问题标题】:How to keep ProGuard from separating inner enum如何防止 ProGuard 分离内部枚举
【发布时间】:2017-12-09 14:57:50
【问题描述】:

我正在尝试保护一个包含内部枚举 (MyInnerEnum) 的面向公众的类 (MyClass) 文件。然而,在 ProGuarding 之后,内部枚举被分离到它自己的类文件MyClass$MyInnerEnum 中。如何防止 ProGuard 分离出内部枚举?我需要能够使用点符号访问内部枚举,例如MyClass.MyInnerEnum.ENUM_VALUE,而不是使用美元符号,例如MyClass$MyInnerEnum.ENUM_VALUE

我的面向公众的课程:

package com.myclass;

public interface MyClass {
    enum MyInnerEnum {
        ENUM_VALUE
    }
}

我已经尝试了这些 ProGuard 配置选项,但无济于事:

<option>-keep enum com.myclass.MyClass** { *; }</option>
<option>-keep enum com.myclass.MyClass$* { *; }</option>
<option>-keep enum com.myclass.MyClass$MyInnerEnum { *; }</option>

【问题讨论】:

  • 将嵌套类放入单独的.class 文件是标准行为,它与proguard 无关。您应该仍然可以使用该点。
  • 嵌套类总是使用Outer$Nested命名模式分解成字节码中的单独类。根据 Java 的文档,这就是 Java 编译。这不会改变人们在源代码中引用嵌套类的方式。这不是“内部枚举”,而是嵌套枚举。接口不能有内部类。 JLS §9.5:“接口中的成员类型声明隐式为 publicstatic。” JLS §8.9:“嵌套枚举类型隐式为 static。”
  • 换一种说法,java虚拟机不知道嵌套类,换句话说,没有办法让嵌套类达到字节码级别。 (这只是编译器的一个技巧,它添加了一些变量和访问方法,因此编译后的类作为嵌套类工作)。不使用 Proguard 将导致相同的结构。
  • 您不能“阻止 Proguard”这样做,因为这样做的不是 Proguard。这是执行此操作的 java 编译器。此外,由于嵌套枚举在定义上是静态的(Lew Bloch 的评论),因此将它们嵌套根本没有意义。您可以通过自己在源代码中进行“防止单挑”。

标签: java enums proguard inner-classes android-proguard


【解决方案1】:

您可以通过保留外部类(在您的案例接口中)和内部枚举来尝试一下。通过将以下行添加到您的 proguard 配置中,这应该可以工作:

-keep interface com.myclass.MyClass
-keep enum com.myclass.MyClass$MyInnerEnum

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。我通过添加解决它:

    # don't proguard all inner enum, need to cooperate with "-keep enum com.companyname.abcd.ClassName$EnumName"
    -keepattributes InnerClasses
    ...
    -keep enum com.myclass.MyClass$MyInnerEnum
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      相关资源
      最近更新 更多