【发布时间】: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:“接口中的成员类型声明隐式为public和static。” JLS §8.9:“嵌套枚举类型隐式为static。” -
换一种说法,java虚拟机不知道嵌套类,换句话说,没有办法让嵌套类达到字节码级别。 (这只是编译器的一个技巧,它添加了一些变量和访问方法,因此编译后的类作为嵌套类工作)。不使用 Proguard 将导致相同的结构。
-
您不能“阻止 Proguard”这样做,因为这样做的不是 Proguard。这是执行此操作的 java 编译器。此外,由于嵌套枚举在定义上是静态的(Lew Bloch 的评论),因此将它们嵌套根本没有意义。您可以通过自己在源代码中进行“防止单挑”。
标签: java enums proguard inner-classes android-proguard