You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置ProGuard保留子类伴生对象常量属性并混淆父类对应属性?

问题:能否通过ProGuard暴露子类引用的父类伴生对象常量,同时混淆父类自身的该常量?

代码场景

父类定义(含伴生对象常量):

open class ParentClass {
...
   companion object {
      ...
      const val CONST_PROPERTY = "value"
   }
}

子类ChildClassFromParentClass继承自ParentClass,无额外定义的伴生对象。

业务代码中通过子类访问该常量:

import package.ChildClassFromParentClass

class OtherClass {

...
   private fun doStuff() {
     val variable = ChildClassFromParentClass.CONST_PROPERTY
   }
...
}

核心疑问

能否配置proguard-rules.pro,让ChildClassFromParentClass.CONST_PROPERTY保持可访问不混淆,但同时混淆ParentClass.CONST_PROPERTY?

已尝试的无效规则

-keepclassmembers class package.ChildClassFromParentClass$** {
    public static ** Companion;
}

解决方案及说明

首先要明确:Kotlin中通过子类访问父类伴生对象成员,只是语法层面的便利,编译后实际还是直接引用父类的伴生对象字段——子类本身不会继承父类的伴生对象,也不会生成自己的Companion实例。你之前的规则无效,就是因为ChildClassFromParentClass根本没有自己的伴生对象。

要实现需求,需配置以下ProGuard规则:

# 1. 保留父类伴生对象的常量字段,确保子类语法调用的底层引用有效
-keepclassmembers class package.ParentClass$Companion {
    public static final java.lang.String CONST_PROPERTY;
}

# 2. 保留子类类名,避免业务代码中对子类的引用失效
-keep class package.ChildClassFromParentClass

# 3. (可选)若需混淆父类的常量名称,可添加以下规则
# 注意:重命名后需确保所有引用路径一致,建议结合上述-keep规则使用
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

规则解释

  1. 第一条规则是核心:因为ChildClassFromParentClass.CONST_PROPERTY编译后等价于ParentClass.Companion.CONST_PROPERTY,必须保留父类伴生对象的这个字段,否则运行时会抛出NoSuchFieldError。
  2. 第二条规则保证子类类名不被混淆,避免业务代码中import package.ChildClassFromParentClass的引用失效。
  3. 第三条可选规则用于混淆父类常量的名称或隐藏源码信息,若需要完全禁止外部直接通过ParentClass访问该常量,还可以添加-dontkeep class package.ParentClass,让父类类名被混淆,切断直接引用路径。

内容的提问来源于stack exchange,提问作者Ronie M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:19